数値解析基礎・演習 Fortran90-(3) if 文, select 文の使い方 ver.2011.05
by user
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 を使うこと を推奨している。