...

数値解析基礎・演習 Fortran90-(3) if 文, select 文の使い方 ver.2011.05

by user

on
Category: Documents
7

views

Report

Comments

Transcript

数値解析基礎・演習 Fortran90-(3) if 文, select 文の使い方 ver.2011.05
数値解析基礎・演習 Fortran90-(3) if 文, select 文の使い方 ver.2011.05
情報環境学専攻(社会・環境系) 斎藤隆泰
1.
はじめに
------------------------------------------------------------------
前回は do 文の基本的な使い方について学んだ。
do 文を使いこなすことができれば、様々な計算を
さて、これまで同様、1 行目から順にできるだ
容易に実行することが可能となるのは前回述べた
け詳しく解説していく。1 行目の program 文でこ
通りである。今回は if 文について学ぶ。if 文も
のプログラムの名前を名付ける。ここでは
Fortran で重要な文法の一つである。英語では小
evenodd とした。プログラムの最後には 13 行目の
さい頃から if を「もし~ならば」のように習って
ように end program 文を記述する。2 行目の
きたと思う。Fortran で使う if 文も、そのような
implicit none は必ず program 文の次の行に付け
感覚で使うことができれば十分である。以下では、
るような癖をつけておく(その理由については、今
if 文について説明し、どのような時に if 文を使え
回の Appendix A で説明してある)。3 行目で整数
ば良いか、しっかり使いこなせるように解説して
変数の a を宣言する。これ以降、プログラム終了
いく。
まで a に適当な整数を代入したりすることができ
るようになる。5 行目は write 文と呼び、write(*,*)
2. if 文
の後の’
’で囲まれた部分を画面に出力するこ
例えば a という整数を入力し(read 文で読み)、
とができる。そのため、5 行目で適当な数を入力
それが偶数か奇数かを判定し、その判定結果を出
してください、という意味のコメントを画面に出
力させるプログラムを作ることを考える。つまり、
力させておき、6 行目でその返答として、read 文
a が偶数であれば’a is even number ‘, a が奇数で
を用いて a の値を読み込む。
あれば’a is odd number’等のように画面に出力さ
せることができれば良いであろう。
7 行目から 11 行目までが if 文である。このプロ
グラムの目的は、もし a が偶数であれば、a は偶
数だということを画面に出力し、a が奇数であれ
------------------------------------------------------------------
ば a は奇数ですよということを画面に出力するこ
1
program evenodd
とであった。つまり、この文章からわかるように、
2
implicit none
3
integer::a
4
「a は偶数ですよ」と出力し
5
write(*,*)’input arbitrary number’
6
read(*,*)a
7
8
9
10
11
もし a が偶数なら
if(mod(a,2)==0)then
a が奇数なら
「a は奇数ですよ」と出力
する
write(*,*)’a is even number’
else
write(*,*)’a is odd number’
end if
ということをプログラムで書ければよいのであ
る。この「もし~なら」という制御文は、fortran
では一般的に if 文と呼ばれている。if 文は
12
13 end program evenodd
if ( 条件式 )then !もし条件式が成り立つなら
~
! 条件式が成り立つ場合の実行文
else ! そうでなければ
~ ! 条件式が成り立たない場合の実行文
end if ! if 文の終わりは end if 文で
7
read(*,*)b
8
9
if (b==0)then
10
write(*,*)’ a is zero’
11
stop
のように使われる。上記を参考に、プログラム
12
end if
の 7 行目を見てみよう。if の直後の ( )の中身は
13
条件式である。ここでの条件式は、mod(a,2)= =0、
14
つまり a を 2 で割った余りがゼロという意味を示
15
している(もちろん、mod(a,3)= =0 なら a を 3 で
16
割った余りがゼロという意味)
。この条件が成り立
------------------------------------------------------------------
write(*,*)’a/b=’,a/b
end program divide
つなら 8 行目が実行され、成り立たない場合は 10
行目が実行される。9 行目の else(そうでないな
このプログラムではプログラム名を divide とし、
ら)を忘れないこと。do 文や program 文同様(end
整数変数として a,b の 2 つを宣言している。5 行
do や end program)、11 行目のように if 文の最後
目で a に 10 を代入し(fortran の=は代入を表し
に end if と if 文の最後を明示的に示す必要がある。
ていたことに注意)7 行目で b の値を入力してい
なお、実行文は、8 行目、9 行目のようにそれぞれ
る。さて、9 行目の if 文の条件式は b= =0 である。
1 行ずつしか書かれていないが、様々な命令を書
11 行目の stop であるが、
もしプログラム中に stop
くことができる。do 文を書き加えたりしても、も
を加えると、そこでプログラムを終了させること
ちろん構わない。
ができる。つまり、ここでは 10/0 というゼロの除
このように、
「もし~ならば」のような条件分岐
を必要とするプログラムを作成する場合に if 文が
算を防ぐために、b がゼロの場合は 10/0 を定義出
来ないので計算を終了させているのである。
役にたつ。( )で囲まれた条件式には、当然なにか
ここで注意すべき事は、先に説明したように
の条件を入れる必要がある。例えば fortran の場
else とその場合の実行文(program evenodd で言
合は科学技術計算を行う場合が多いので、必然的
えば、9 行目と 10 行目)が記述されていない。こ
に a>b や a>=0 等といった直感的に数学で用いる
のように、
「もし~ならば~を実行し、そうでない
表現を利用する場合が多い。
ならば~を実行する」の「そうでないならば~を
また、次のプログラム例を見てみよう。次のプ
ログラムは整数 a(ただし a=10 とする)を整数 b
で割った場合の商を求めるプログラムである。
実行する」の部分は省略することができるのであ
る。
このように、ここでは代表的な if 文の使い方に
ついて述べた。if 文のさらなる詳しい使い方等は、
-----------------------------------------------------------------1
program divide
2
implicit none
3
integer::a,b
4
シラバスで紹介している図書等を参照して欲しい。
3. select 文
さて、ここで紹介した if 文は、条件分岐の数が
高々2 つである。つまり、偶数か、奇数かのよう
5
a=10
に、条件式の後に実行できる実行パターンは
6
write(*,*)’input arbitrary number b’
program evenodd を例にとれば、8 行目を経由す
るか 10 行目を経由するかの 2 つである。
fortran90
14
では、数多くの分岐に対応できるよう、select 文
15
というものも存在する。
16
select 文の利用例として、次のような問題につ
いてプログラムを作成することを考えよう。
問題
case(1)
c=a-b
case(2)
17
18
c=a*b
case(3)
19
c=a/b
20
case default
まず、実数 a と実数 b を入力する。次に、整数
21
write(*,*)’invalid number’
sw を準備し sw が 0 ならば a と b の和を、sw が
22
stop
1なら a と b の差を、sw が 2 ならば a と b の積
23
end select
を、sw が 3 ならば a と b の除算結果を c に代入し
24
て出力するプログラムを作成せよ。
25 write(*,*)’output,c=’,c
26
この問題に対するプログラムを、これまでに述
べた if 文の使い方に習って作成しようとすると、
27
end program selection
------------------------------------------------------------------
なかなか上手に行かないことに気づくであろう。
なぜなら、sw の値が 0~3 のいずれかを取るかに
上のプログラムの解説をしていこう。3 行目で
よって、それぞれ異なる条件分岐をさせなければ
整数変数 sw を宣言した後、4 行目で実数 a,b,c を
ならない。条件分岐による異なる実行命令は 4 つ
宣言している。7 行目で実数 a と b をそれぞれ順
必要である。このように、多くの分岐が必要とな
番にキーボードから入力して read 文で読ませて
る場合、select 文の利用が便利である。select 文
いる。9 行目では整数 sw に値をキーボードから読
を用いた場合、この問題に対するプログラムは次
ませている。さて、11 行目から 22 行目までがこ
のように書ける。
こで紹介する select 文である。select 文は通常、
次のような形式で用いられる。
-----------------------------------------------------------------1
program selection
select case(整数変数)
2
implicit none
case(0)
3
integer::sw
4
real(8)::a,b,c
! 整数変数の値が 0 なら
整数変数が 0 の場合の実行文
case(1)
! 整数変数の値が 1 なら
整数変数が 1 の場合の実行文
5
case(2)
! 整数変数の値が 2 なら
6
write(*,*)’input a and b’
7
read(*,*)a,b
整数変数が 2 の場合の実行文
8
write(*,*)’input sw for calculations’
:
9
read(*,*)sw
:
case default ! 整数変数の値が上記以外なら
10
11
select case(sw)
12 case(0)
13
c=a+b
整数変数が上記の case(ケース)文に
該当しない場合の実行文
end select
について学ぶ。
最初の select case 文の後の(
)内に条件分岐
の指標となる整数変数を書いておく。ここで用い
Appendix A implicit none 文
た整数変数の値に応じて、どの case 文を実行する
さて、第 1 回の演習から program 文の次の行に
かが決定される。case 文は何通りも書くことがで
は implicit none 文を書くことについて述べてき
きる。最後の case default 文は整数変数がどの
た。説明を後回しにしたのは、fortran77 との違い
case(ケース)にも該当しない値を持っていた場合
についても説明しないといけないからである。さ
に実行される。なお、case default 文の領域(青
て、これを説明するために次のプログラム
文 字 の 部 分 ) は 省 略 す る こ と も で き る 。 case
compimp1 を見て欲しい。
default 文を省略した場合、整数変数の値がいずれ
の case 文にも該当しなければ、何も実行されるこ
------------------------------------------------------------------
となく select case 文が終了する。
1
program compimp1
これより、9 行目で読ませた整数変数を select
2
case 文の指標として 11 行目で用いて、case 0 か
3
write(*,*)’input arbitrary number’
ら case 3 までをそれぞれ、和、差、積、除算の計
4
read(*,*)i
算の条件分岐に用い、それ以外のケースは 21 行目
5
で不適切な値ですよと画面に出力させ、22 行目の
6
stop 文でプログラムを終了させている。計算結果
7
は 25 行目の write 文で出力している。
8
以上が select 文を用いた条件分岐の例である。
write(*,*)’your input number is’,i
end program compimp1
------------------------------------------------------------------
このように条件分岐数が多数ある場合は select 文
を用いた方がすっきりする。ただし、select 文は
このプログラム compimp1 はキーボードから適
fortran77 にはない文法である。fortran90 以降の
当な整数を入力し、それを整数変数 i に格納し、i
コンパイラでないと利用できないことに注意され
の値を画面に出力させるプログラムである。この
たい。このように、fortran90 以降で利用できる便
プログラムを見て、何か違和感を感じるだろう
利な文法は数多い。その他にも fortran90 は構造
か?違和感を感じる読者は、少しずつであるが着
体やポインタにも対応している。
実に fortran について理解してきている。何が違
和感の原因かというと、program 文の次の行に
3
if 文, select 文利用のまとめ
implicit none がないことと、4 行目に整数変数 i
今回は fortran で条件分岐を行う場合の方法に
が利用されているにも関わらず、integer::i のよう
ついて説明した。fortran では条件分岐を行うため
な整数変数の宣言がなされていないことである。
に、if 文と select 文が用意されている。select 文
そのため、fortran90 を利用するこの講義を受講し
は多数の条件分岐を扱う場合に便利である。ここ
ている読者が、上のプログラムを書き直した場合
では説明を省略したが、if 文でも多数の条件分岐
は、2 行目と 3 行目にそれらを記述した次の新し
を実行することはできる。自分でプログラムを作
いプログラム compimp2
成するときに、どちらを使った方がプログラムを
書きやすいか等、様々なことを考えながら適宜 if
------------------------------------------------------------------
や select 文を用いればよい。次回は subroutine
1
program compimp2
2
implicit none
3
integer::i
-----------------------------------------------------------------このプログラム compimp3 の誤りは 6 行目にあ
4
5
write(*,*)’input arbitrary number’
る。6 行目で画面に出力させるべき整数変数は、
6
read(*,*)i
本来なら i であるはずが、ii になっている。その
7
8
ため、このプログラムをコンパイルし、実行でき
write(*,*)’your input number is’,i
たとしても、6 行目の実行結果では ii の値を出力
9
してしまう。入力に用いた変数は 4 行目のように
10 end program compimp2
i であるため、自分で入力した値が 6 行目で出力さ
------------------------------------------------------------------
れない。ii の値は 6 行目時点で不定であるため、
当然、正しい数値が出力されないことになる。
を作成してくれるだろう。
この間違いの原因は、暗黙の型宣言を用いたこ
ただし、ここで注意すべきことは、2、3 行目を
とにある。暗黙の型宣言を用いたため、自分が利
記述しない compimp1 でも正しい結果が得られて
用する予定でなかった変数 ii が 6 行目にいたとし
しまうことである。それはなぜかというと、
てもコンパイルが成功し、計算を実行できてしま
fortran77 では暗黙の型宣言というルールが存在
ったのである。暗黙の型宣言の利用を防ぐには、
するからである。暗黙の型宣言とは、program 中
program 文の次の行に、implicit none を記述すれ
で例えば i,j,k,l,m そして n から始まる変数は自動
ばよい。つまり implicit none は暗黙の型宣言を使
的に整数変数と認識され、宣言をしなくても利用
用しませんという命令だったのである。もし、プ
できるというルールである。つまり、最初のプロ
ログラム compimp3 の 2 行目に implicit none 文
グラム compimp1 は 4 行目で整数変数 i を利用し
を付け加えてコンパイルすると、コンパイルの段
ているが、それが i から始まるため、暗黙の型宣
階でエラーが表示され、
「6 行目に、宣言していな
言の適用により宣言をしなくとも i が整数変数で
い変数 ii が利用されています」といった趣旨のメ
あるとコンパイラが勝手に認識しているのである。 ッセージが表示され、間違いに気づくことができ
これは安易に考えると、宣言を省略できるので楽
る。先の例は数行程度のプログラムであるので、6
だと思うかもしれない。では、そう思った読者は
行目の ii は正しくは i だと簡単に間違いを見つけ
暗黙の型宣言を用いた次のプログラムの間違いを
ることができるかもしれない。ただし、実用的な
すぐに発見できるであろうか?
プログラムは数百、数千行に渡ることを考えれば、
そのような長いプログラムから間違いを見つける
-----------------------------------------------------------------1
program compimp3
ことは簡単ではないのである。
こ れ が 、 こ れ ま で program 文 の 次 の 行 に
implicit none をおまじないのように書きなさいと
2
3
write(*,*)’input arbitrary number’
いった理由である。implicit none はこのように暗
4
read(*,*)i
黙の型宣言を用いないようにする命令である。本
講義では、暗黙の型宣言を使わずに、implicit none
5
6
write(*,*)’your input number is’,ii
ことを推奨する。実際、fortran90 に関する他の多
7
8
を用いて、必要な変数は全て自分の手で宣言する
end program compimp3
くの図書も、そのように implicit none を使うこと
を推奨している。
Fly UP