情報処理概論
工学部 物質科学工学科
応用化学コース
機能物質化学クラス

第６回
２００５年 ５月２６日

先週の演習2： 円柱の体積
z 半径と高さを入力すると円柱の体積を計算して表示するプログラムを作成する
z read文を利用してキーボードからデータを入力する
z πは atan を利用して生成

先週の演習の正解例
program pillar
implicit nonereal(8) :: r, h, pi
intrinsic atanpi = 4.0D0 * atan(1.0D0)
write(*, *) 'Takasa: 'read(*, *) hwrite(*, *) 'Hankei: 'read(*, *) rwrite(*, *) 'Taiseki = ', h * r * r * pi
stopend program

型の混在
z 整数型と実数型の演算が混在する場合型の「強い」方に変換される
強さ： 倍精度実数＞単精度実数＞整数
z 以下は同じ結果

4.0D0 * 3.0D0 / 7.0D0
4.0 * 3.0D0 / 7.0D0
4 * (3.0D0 / 7)

プログラム作成の際の注意点
z型が混在するプログラムを記述する場合十分な注意が必要

z以下は結果が異なる
4.0D0 * 3.0D0 / 7.0D0
4.0D0 * (3.0 / 7.0)
4 * 3 / 7
4.0D0 * (3 / 7)
⇒ 用心のため, 型を揃えた方が良い．

○ 条件分岐・

繰り返し・型変換

先週の演習でz 入力された高さや半径が０以下の場合入力ミスとして表示し終了するようにしたい．

% ./pillar
Takasa: -10.0
Error: Takasa must be > 0.0%

条件分岐： if 文の利用
（もし～ならば）z

条件を満たす場合のみ実行例)
もし h が 0.0 以下ならばError: Takasa must be > 0.0 と表示して終了
write(*, *) 'Takasa: 'read(*, *) hif (h <= 0.0D0) thenwrite(*, *) 'Error: Takasa must be > 0.0'
stop
end ifif 文の利用法（１）z もし～ならばif (条件) then
条件を満たす場合の処理
end if

条件
z if 文で利用できる主な条件

新表記

旧表記

意味>

.gt.

より大きい

<.lt.

より小さい>=.ge.

以上<=.le.

以下/=.ne.

等しくない==.eq.

等しい= を2個並べる.
1個だけだと変数への代入の意味になるので注意if 文の利用例
z 降水確率と傘
z５０％以上なら”傘を持っていきなさい”

program pillarimplicit none
integer :: probwrite(*, *) 'Probability of the rain: 'read(*, *) prob
if (prob >= 50) thenwrite(*, *) "May be it will rain."write(*, *) "Don't forget to bring an umbrella!"end ifstop
end program

条件分岐
z

先週までのプログラムの流れz

処理1

上から順に実行

処理2
処理3
処理4

z

条件分岐を含むプログラムの流れz

条件によって処理が変わる

処理1

条件を満たす？
Yes
No
処理2

処理3

もっと複雑な条件分岐z

条件を満たさない場合の処理

条件を満たす？
Yes
No
処理1

z

さらに条件を付ける

処理3

条件Aを満たす？
No
Yes
条件Bを満たす？
Yes
No

条件Cを満たす？
Yes
No

処理1

処理3

処理2

処理2

処理5

処理4

条件を満たさなかった場合の処理
z ５０％以上なら ”傘を持っていきなさい”

さもなければ ”持っていかなくてもいいかも”

if (prob >= 50) thenwrite(*, *) "May be it will rain."write(*, *) "Don't forget to bring an umbrella!"elsewrite(*, *) "May be it will not rain."write(*, *) "You may go without an umbrella."end ifif 文の利用法（２）z もし～ならば～さもなくば～

if (条件) then
条件を満たす場合の処理
else
条件を満たさない場合の処理
end if
条件を満たす？
YesNo
処理1

処理2
処理3

もっと細かくz７０％以上なら ”持っていきなさい”
５０％以上なら ”持っていったほうがいいよ”
３０％以上なら ”持っていかなくてもいいよ”
さもなければ ”いらないよ”

if (prob >= 70) thenwrite(*, *) "Don't forget to bring an umbrella!"else if (prob >= 50) thenwrite(*, *) "You should bring an umbrella."else if (prob >= 30) thenwrite(*, *) "You may go without an umbrella."elsewrite(*, *) "You don't need an umbrella."
条件Aを満たす？
end ifNo

Yes

処理1

条件Bを満たす？
Yes
No
処理2
条件Cを満たす？
Yes
No
処理3
処理4
次の処理

if 文の利用法（3）z

もし(条件A)ならば～さもなくば，もし(条件B)ならば～さもなくば，もし(条件C)ならば～...
さもなくば～

if (条件A) then
条件Aを満たす場合の処理
else if (条件B) then
条件Aを満たさず，条件Bを満たす場合の処理
else if (条件C) then
条件Aも条件Bも満たさず，条件Cを満たす場合の処理...
else
どの条件も満たさない場合の処理
end if”または” と ”かつ”
z 条件１

または 条件２（条件１ .or. 条件２）

z 条件１

かつ 条件２（条件１ .and. 条件２）
前後のピリオドを忘れずに！

.or. の利用例z

降水確率が 0未満 または 100より大きい場合
エラー
if ( prob < 0 .or. prob > 100 ) thenwrite(*,*) "Error: Wrong probability ", prob
stop
else if (prob >= 70) thenwrite(*,*) "Don't forget to bring an umbrella!"else if (prob >= 50) thenwrite(*,*) "You should bring an umbrella."else if (prob >= 30) thenwrite(*,*) "You may go without an umbrella."elsewrite(*,*) "You don't need an umbrella."end if.and. の利用例z

降水確率が 0未満 または 100より大きい場合
エラー
if ( prob >= 0 .and. prob <= 100 ) thenif (prob >= 70) thenwrite(*,*) "Don't forget to bring an umbrella!"else if (prob >= 50) thenwrite(*,*) "You should bring an umbrella."else if (prob >= 30) thenwrite(*,*) "You may go without an umbrella."elsewrite(*,*) "You don't need an umbrella."end ifelsewrite(*,*) "Error: Wrong probability ", prob
stop
end ifもう一つの方法
select 文z select 文の利用例
select case(prob)case(70:100)
write(*, *) "Don't forget to bring an umbrella!"case(50:69)
write(*, *) "You should bring an umbrella."case(30:49)
write(*, *) "You may go without an umbrella."case(0:29)
write(*, *) "You don't need an umbrella."case default
write(*, *) "Error: Wrong probability ", prob
stop
end selectselect文の利用法
select case(式)case(値１)
式の値が値１に含まれる場合の処理
case(値２)
式の値が値２に含まれる場合の処理．．．
case default
式の値がどの値にも含まれない場合の処理
end selectz

式は整数型か文字型か論理型
zz

実数は不可

どの値にも含まれない場合の処理
case default は省略可

case で指定できる値
zzz

数値，文字のみ例) ２０の場合‘d’ の場合case(20)case('d')

数値や文字列の範囲例) ０～１０の場合‘a’ ~ ‘e’ の場合
５０以下の場合'n'以降の文字の場合case(0:10)
case('a':'e')case(:50)
case('n':)複数の値例) 1，5，10 の場合‘c‘，’t’ の場合case(1,5,10)case('c','t')

・

条件分岐

○繰り返し・型変換

繰り返しz 以下のように 2i(i = 1~10) を表示するプログラムを作るには?
2** 1:
2** 2:
2** 3:
2** 4:
2** 5:
2** 6:
2** 7:
2** 8:
2** 9:
2**10:
Done!

248
16
32
64
128
256
5121024

方法１：全部書く
program power_1
write(*, '(a,i10)') '2** 1:',2**1
write(*, '(a,i10)') '2** 2:',2**2
write(*, '(a,i10)') '2** 3:',2**3
write(*, '(a,i10)') '2** 4:',2**4
write(*, '(a,i10)') '2** 5:',2**5
write(*, '(a,i10)') '2** 6:',2**6
write(*, '(a,i10)') '2** 7:',2**7write(*, '(a,i10)') '2** 8:',2**8
write(*, '(a,i10)') '2** 9:',2**9write(*, '(a,i10)') '2**10:',2**10
write(*, *) 'Done!'stop
end programz

現実的ではないzz

数が多くなると大変．例えば i=1~1000
範囲が変わると全部書き換え．例えば i=20~30

方法２： 繰り返しを使う
z

i を 1 から 1つずつ増やしながら１０まで繰り返す
z

繰り返しの内容：
write(*, ‘(“2**”, i4, “:”, 1x, i10)’) i, 2**ii と 2^i を表示

program power_2
implicit none
integer :: ido i=1,10
write(*, '("2**", i4, ":", 1x, i10)') i, 2**i
end dowrite(*, *) 'Done!'stop
end program実行イメージz プログラム
do i = 1, 10write(*, '("2**", i4, ":", 1x, i10)') i, 2**i
end doi=1 write(*, '("2**", i4, ":", 1x, i10)') 1, 2**1
i=2 write(*, '("2**", i4, ":", 1x, i10)') 1, 2**2
i=3 write(*, '("2**", i4, ":", 1x, i10)') 1, 2**3…
i=10 write(*, '("2**", i4, ":", 1x, i10)') 1, 2**10

繰り返しz今までのプログラムの流れz

条件分岐

各処理は高々一回実行

処理1

z

繰り返しを含むプログラムの流れ
z

処理2
処理3

指定された条件を満たす間同じ処理を繰り返して実行する
まだ繰り返しの条件を満たしてる？
NoYes
処理1

処理2

do文の利用法z

制御変数の値を 開始値 から 増分 ずつ増やしてゆき，終了値 以上になるまで繰り返す
do 制御変数 = 開始値，終了値 [，増分]繰り返す処理省略可能

end doz

増分を省略すると１が指定されたとみなされるz

増分は負の値でも良い．
z この場合, 制御変数を開始値から増分ずつ減らしてゆき,終了値以下になるまで繰り返す．
例） do i = 100, 0, -5

開始値，終了値は変数でも構わない
z 例）

開始値,終了値を実行時に入力する．

program power_3
implicit none
integer :: i,start,end
write(*, '(a$)') 'Start: 'read(*, *) start
write(*, '(a$)') 'End: 'read(*, *) end
do i=start,end
write(*, '("2**",i4, ":", 1x, i10)') i, 2**i
end dowrite(*, *)stop
end program'Done!'

do文利用上の注意
z do文の繰り返し処理中，制御変数の値を変化させないz

途中で値が変化すると繰り返しが正常に終了しない
z 誤りの例:

do i=1,10
i = 1
write(*, '("2**",i2, ":", 1x, i5)') i, 2**i
end do文の組み合わせz 実際のプログラムでは if文や do文を組み合わせて記述する
z 注意： do と end do, if と end if は入れ子構造
program sample1
implicit none
integer :: i,nwrite(*, *) 'Enter N :'read(*, *) nif (n <= 0) thenwrite(*, *) 'Error: N must be > 0'else
do i = 0, nwrite(*, *) '2**', i, '=', 2**i
end doend ifstop
end program何重に重ねても良い
program sample1
implicit none
integer :: i, j, nwrite(*, *) 'Enter N :'read(*, *) nif (n <= 0) thenwrite(*, *) 'Error: N must be > 0'else
do i = 1, n
do j = 1, nwrite(*, *) i, ' * ', j, ' = ', i * j
end doend do
end ifstop
end program

・

条件分岐・繰り返し○型変換

型の変換： 整数→実数dble関数 (倍精度実数型へ)
z 制御変数や番号に用いている整数値を実数の計算に利用する場合等
program toreal
implicit none
integer :: ireal(8) :: piintrinsic dble,cos,atanpi = 4.0D0 * atan(1.0D0)
do i=1,6write(*, *) 'cos(pi/',i,')=', cos(pi/dble(i))
end dostop
end program

型の変換:

実数→整数

int関数, ceiling関数, nint関数
z 小数点以下の扱いによって使い分けz

切り捨て int例） int(4.2) → 4z

切り上げ ceiling例） ceiling(3.1) → ４z

四捨五入 nint例） nint(4.495) → ４

プログラムの字下げの勧め
zプログラムの構造にあわせて字下げすると良いzz

if の条件を満たした場合の処理やdo文で繰り返される処理など→ プログラムの相互関係がわかりやすい
例えば，下げ幅は２文字ずつもしくは４文字ずつif ( prob>=0 .and. prob<=100) thenif (prob >= 70) thenwrite(*, *) "Don't forget to bring an umbrella!"else if (prob >= 50) thenwrite(*, *) "You should bring an umbrella."else if (prob >= 30) thenwrite(*, *) "You can go without an umbrella."elsewrite(*, *) "You don't need an umbrella."end ifelsewrite(*, *) "Error: Wrong probability ", probstop
end if字下げの有無による見栄えの違い
program sample1
implicit none
integer :: i, j, nwrite(*, *) 'Enter N :'read(*, *) nif (n <= 0) thenwrite(*, *) 'Error: N must be > 0'else
do i = 1, n
program sample1
do j = 1, n
implicit nonewrite(*, *) i, ' * ', j, ' = ', i * j
integer :: i, j, n
end doend dowrite(*, *) 'Enter N :'end ifread(*, *) nstopif (n <= 0) thenend program
write(*, *) 'Error: N must be > 0'else
do i = 1, n
do j = 1, nwrite(*, *) i, ' * ', j, ' = ', i * j
end doend doend ifstop
end program