FORTRANプログラミング入門 7回 多重ループと条件付き反復処理

木村拓馬
FORTRAN プログラミング入門
–第 7 回 多重ループと条件付き反復処理–
木村拓馬
2014 年 5 月 23 日 11:18
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
1/17
木村拓馬
.
本日は
.
.
条件付き反復処理
条件式が成立したら反復終了
条件式が成立している間繰り返す
多重ループ
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
2/17
木村拓馬
DO 構文(DO LOOP)
.
DO 構文の基本形1:
繰り返すたびに変数を増分値ずつ増やし,終値を超えた時点で反復終了
.
[ラベル:] DO 変数名=初期値, 終値, 増分値
繰り返し実行する処理 (何行でもよい)
END DO [ラベル]
.
.
DO 構文の基本形2:条件式が成立している間繰り返す
.
[ラベル:] DO WHILE(条件式)
繰り返し実行する処理 (何行でもよい)
END DO [ラベル]
.
.
DO 構文の基本形3:条件式が成立したら反復終了
.
[ラベル:] DO
繰り返し実行する処理 (何行でもよい)
IF (条件式) EXIT
繰り返し実行する処理 (何行でもよい)
.
END DO [ラベル]
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
3/17
木村拓馬
反復回数を指定しない DO 文
DO 構文において,DO 変数を省略した場合,無限ループになる.
”繰り返しをやめる条件 ”を明示的に記述しループを終了する.
.
例 7.1a:条件式が成立したら反復終了
.
DO
READ(*,*) A
IF (A == 0) EXIT
WRITE(*,*) A*A
END
DO
.
ただし,終了条件に実数を用いる場合は注意が必要.
例 7.1b では,計算結果がぴったり 0.0 にならない限り無限に繰り返す.
絶対値 (ABS) が十分小さくなったら繰り返しを終了すると良いかも.
.
例 7.1b:注意が必要な終了条件
.
DO
…
IF (A == 0.0) EXIT
…
END
DO
.
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
.
例 7.1c:わりと安全な終了条件
.
DO
…
IF (ABS(A) <= 1.0E-6) EXIT
…
.END DO
4/17
木村拓馬
WHILE を用いた DO 構文
ある条件が満たされる限り,繰り返し処理を行なう.
.
例 7.2a:WHILE を用いない例
.
DO I = 1, 10
WRITE(*,*) I
END
DO
.
.
例 7.2c:WHILE を用いない場合
.
DO
…
IF (ABS(A) <= 1.0E-6) EXIT
…
END
DO
.
.
例 7.2b:WHILE を用いた DO 構文の例
.
I = 1
DO WHILE (I <= 10)
WRITE(*,*) I
I = I + 1
END
DO
.
.
例 7.2d:WHILE を用いた DO 構文
.
DO WHILE (ABS(A) > 1.0E-6)
…
…
.END DO
0
[1] DO 制御が [,] WHILE( スカラ論理式 ) の形である場合,DO 制御を省略して次の文を DO ブロッ
クの先頭に挿入した場合と同じ効果をもつ。IF (.NOT. (スカラ論理式 )) EXIT
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
5/17
木村拓馬
!1 から 10 までの 2 乗を表示
.
例)回数を指定して反復 (ex6.3.f90).
.
1
!1 から 10 までの 2 乗を表示(ラベルなし)
2
3
4
5
.6
PROGRAM REI_DO1
DO I = 1, 10
WRITE(*,*) I, I*I
END DO
END PROGRAM
.
例)条件が成立したら反復終了 (ex7.3.f90).
.
1
2
3
4
5
6
7
.8
PROGRAM REI_DO2
I=1
DO
WRITE(*,*) I, I*I
I=I+1
IF(I>10) EXIT
END DO
END PROGRAM
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
.
例)条件が成立している間繰り返す (ex7.4.f90).
.
1
2
3
4
5
6
.7
PROGRAM REI_DO3
I=1
DO WHILE (I <= 10)
WRITE(*,*) I, I*I
I=I+1
END DO
END PROGRAM
6/17
木村拓馬
多重ループ
DO 構文は交差させない限り何重になっても構わない.
DO 構文が多重になることを多重ループと呼ぶ.
.
例 7.5a:二重ループ
.
DO I = 1, 10
DO J = 1, 10
WRITE(*,*) I, J
END DO
END
DO
.
.
例 7.5b:ラベルあり二重ループ
.
LOOP1: DO I = 1, 10
LOOP2:
DO J = 1, 10
WRITE(*,*) I, J
END DO LOOP2
END DO LOOP1
.
DO と END DO との対応を見やすくするためにインデント(字下げ)する
こと.
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
7/17
木村拓馬
多重ループ
.
例 7.6a:二重ループ
.
DO I = 1, 10
DO J = 1, 10
WRITE(*,*) I, J
END DO
DO K = 10, 1, -1
WRITE(*,*) I, K
END DO
END
DO
.
.
例 7.6b:ラベルあり二重ループ
.
LOOP1: DO I = 1, 10
LOOP2:
DO J = 1, 10
WRITE(*,*) I, J
END DO LOOP2
LOOP3:
DO K = 10, 1, -1
WRITE(*,*) I, K
END DO LOOP3
END
DO LOOP1
.
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
8/17
木村拓馬
多重ループ
.
例 7.7a:三重ループ
.
DO I = 1, 10
DO J = 1, 10
DO K = 1, 10
WRITE(*,*) I, J, K
END DO
END DO
END
DO
.
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
.
例 7.7b:ラベルあり三重ループ
.
LOOP1: DO I = 1, 10
LOOP2:
DO J = 1, 10
LOOP3:
DO K = 1, 10
WRITE(*,*) I, J, K
END DO LOOP3
END DO LOOP2
END DO LOOP1
.
9/17
木村拓馬
多重ループ
DO 構文は交差してはならない.
.
例 7.8:多重ループの悪い書き方(ex7.8.f90)
.
1
2
3
4
5
6
7
.8
PROGRAM DODO
INTEGER :: I, J
LOOP1: DO I = 1, 10
LOOP2:
DO J = 1, 10
WRITE(*,*) I, J
END DO LOOP1
END DO LOOP2
END PROGRAM
g95 では以下のようなエラーメッセージが出てコンパイルできない:
.
In file ex7.8.f90:6
END DO LOOP1
1
Error:
Expected label ’loop2’ for END DO statement at (1)
.
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
10/17
木村拓馬
書式指定(文字書式仕様書式識別子)
これまで使用してきた「write(*,*)」では,表示がきれいに揃わないことがある.
編集記述子を用いて表示桁数などの書式を指定することにより,出力を見やすくできる.
.
よくつかう編集記述子(データ編集記述子)
.
I 型編集記述子 (Iw)
整数型データの入出力に用いる.全部で w 桁で右詰め表示.
F 型編集記述子 (Fw.d)
実数型データの入出力に用いる.全部で w 桁,小数点以下 d 桁で,右詰めで表示.
E 型編集記述子 (Ew.d[e x])
実数型データの指数部付き入出力に用いる.全部で w 桁,小数点以下 d 桁で,右詰めで表示.
x は指数部の桁数(省略できる).E10.2e1 のように書く
A 型編集記述子 (Aw)
.
文字型データの入出力に用いる.全部で w 文字,右詰めで表示.
1
[1] 書式付き入出力文中の書式識別子が文字式である場合,それを評価して得られる文字列の先頭
の部分が正しい書式仕様を形成しなければならない。
書式仕様は,左括弧で始まり右括弧で終わる。
編集記述子 (edit descriptor) は,データ編集記述子 (data edit descriptor),制御編集記述子 (control edit
descriptor) 又は 文字列編集記述子 (character string edit descriptor) とする。
R1005 データ編集記述子 is I w [ . m ] or B w [ . m ] or O w [ . m ] or Z w [ . m ] or F w . d or E w . d [ E e ]
or EN w . d [ E e ] or ES w . d [ E e ] or G w . d [ E e ] or L w or A [ w ] or D w . d or DT [文字定数表現] [(
値指定並び )]
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
11/17
木村拓馬
ここでは,write(*,*) の右側の*の部分(書式識別子)に書式を書く方法を紹介する.
write(*,fmt=’(i3)’) のように右側の*の部分に書式を記述する.fmt=を省略し write(*,’(i3)’) でもよい 1 .
ここで’(i3)’ は,
「3 ケタの整数を1つ」を意味する.
「10 ケタでうち 3 ケタが小数点以下の実数を1つ」ならば’(f10.3)’,
「10 ケタでうち 3 ケタが小数点以下の実数を2つ」ならば’(f10.3, f10.3)’,または’(2f10.3)’,
のように書く.小数点や符号の分の桁を忘れないよう注意すること.
.
例:表示桁数の指定 (syosiki.f90)
.
1 program syoshiki
2
integer :: i=1, j=12, k=123
3
real :: a=1.234, b=12.3456
4
character(5) :: string=’chara’
5
write(*, fmt=’(i3)’) i
6
write(*, ’(i3)’) i
7
write(*, ’(i5, i5, i5)’) i, j, k
8
write(*, ’(3i5)’) i, j, k
9
write(*, ’(2f10.3)’) a, b
10
write(*, ’(a5)’) string
11
write(*, ’(a4)’) string
12
end program syoshiki
.
.
実行すると
.
1
1 123 12
1 123 12
1.234 12.346
chara
char
.
1
[1] 先行する FMT= を省略して書式識別子を指定する場合,書式識別子は,データ転送指定子並びの 2 番目の項目
でなければならず,そのとき最初の項目は,装置識別子でなければならない。
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
12/17
木村拓馬
.
例:表示桁数の指定 (syosiki.f90)
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.
! 桁数を揃えて表示する
program sin_degree
real:: rad
integer:: i
rad=acos(-1.0)/180.0
do i=0,360,30
write(*,’(a4, i4, a9, f10.7)’) ’sin(’,i,’ degree)=’, sin(i*rad)
end do
write(*,*)
!以下の書き方でも OK
do i=0,360,30
write(*,’(’’sin(’’, i4, ’’ degree)=’’, f10.7)’) i, sin(i*rad)
end do
end
.
実行すると以下のが2つ
.
.
書式指定なし(write(*,*) のみ)だと
.
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
.
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
sin(
. sin(
0
30
60
90
120
150
180
210
240
270
300
330
360
degree)= 0.0000000
degree)= 0.5000000
degree)= 0.8660254
degree)= 1.0000000
degree)= 0.8660253
degree)= 0.5000001
degree)=-0.0000001
degree)=-0.5000000
degree)=-0.8660254
degree)=-1.0000000
degree)=-0.8660254
degree)=-0.5000002
degree)= 0.0000002
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
0 degree)= 0.
30 degree)= 0.5
60 degree)= 0.86602545
90 degree)= 1.
120 degree)= 0.8660253
150 degree)= 0.50000006
180 degree)= -8.742278E-8
210 degree)= -0.5
240 degree)= -0.86602545
270 degree)= -1.
300 degree)= -0.86602545
330 degree)= -0.5000002
360 degree)= 1.7484555E-7
13/17
木村拓馬
以下の例のように,ADVANCE 指定子 1 を記述することで,改行するかしないかを指定できる.
ここの環境では ADVANCE 指定子を記述する場合は fmt=を省略できない様子.
.
例:改行 (syosiki.f90)
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.
program kaigyou
!改行する
write(*, fmt=’(a6)’) ’ 改行’
write(*, fmt=’(a6)’) ’ する’
!改行する
write(*, *) ’ 改行\n する\n’
!改行しない
write(*, fmt=’(a6)’, advance=’no’) ’ 改行’
write(*, fmt=’(a9)’, advance=’no’) ’ しない’
!改行しない
write(*, fmt=’(a6,$)’) ’ 改行’
write(*, fmt=’(a9,$)’) ’ しない’
!改行する
write(*, fmt=’(a6)’, advance=’yes’) ’ 改行’
write(*, fmt=’(a6)’, advance=’yes’) ’ する’
end program
.
実行すると
.
改行
する
改行
する
改行しない改行しない改行
する
.
1
[1] データ転送文の ADVANCE 指定子 スカラ基本文字式の値は,YES 又は NO でなければならない。ADVANCE
指定子は,その子入出力文でない入出力文が前進入出力を行うかどうかを指定する。YES を指定すると,前進入出力が
行われる。NO を指定すると,停留入出力が行われる (9.2.3.1)。
2
日本語は2バイト文字だから 「fmt=’(a2)’」で1文字,とかいうけど,環境によっては「fmt=’(a3)’」で1文字としな
いと文字化けする.unicode は3バイト文字とか4バイト文字とか混ざっているので足りないのか?要確認.
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
14/17
木村拓馬
参考文献
[1]
JIS X 3001-1:2009 (プログラム言語 Fortran – 第 1 部:基底言語)
[2]
戸川隼人:ザ・Fortran90/95,サイエンス社(1999)
[3]
陳 小君, 山本哲朗: 英語で学ぶ数値解析, コロナ社(2002)
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
15/17
木村拓馬
Appndix
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
16/17
木村拓馬
CYCLE 文と多重ループ
多重ループの中では,CYCLE にラベルを指定すると,指定したラベルまで処理を飛び越す
.
例)CYCLE +ラベル (ex7.9.f90).
.
1
! --- 足して S 以下の組み合わせだけ表示 --2
PROGRAM CYCLE2
3
INTEGER :: I, J, S=4
4
LOOP1: DO I=1,4
5
DO J=1,4
6
IF(I+J>S) CYCLE LOOP1
7
WRITE(*,*) I,’+’,J,’=’,I+J
8
END DO
9
END DO LOOP1
END
.10
.
ex7.9.f90 を実行すると
.
1 + 1 = 2
1 + 2 = 3
1 + 3 = 4
2 + 1 = 3
2 + 2 = 4
. 3 + 1 = 4
FORTRAN プログラミング入門,–第 7 回 多重ループと条件付き反復処理–
17/17