. (fortranメモ) (後藤資料) (後藤班Linux) (構造解析プログラム) (Ruby入門)
[90プログラミング] [教育用の言語] [FortranとLinux] [本物のプログラマ] [Fortranを使おう] [歴史] [77ってどう?] [Wiki] [90/95/2000規格]

フォートラン(gfortran)入門

以下は、「情報処理の技法G」の Fortran90用のテキストをg77用に 書き換えたものをgfortran用に書き換えつつあるものです。 なお以下では、 gfortranで使えるFortran90的な書式を取り入れていますが、 古典的なFortran77の書式との対応については、 [fortranメモ] 参照。

代数計算プログラム例はこちら


目次

  1. . Fortranの基礎、UNIX 上でのコンパイルと実行
  2. Fortranで簡単なプログラムを作成(2回目)
  3. Fortranで簡単なプログラムを作成(3回目)

Fortranの基礎、UNIX 上でのコンパイルと実行

gcc (GNU Compiler Collection) のフォートランコンパイラーのg77というのは、 (古典的で時代遅れな)FORTRAN77Fortran90の機能の一部 も利用できるように拡張されたフォートランコンパイラーです。 g77ではFortran90の機能の一部しか利用できませんが、  Fortran90の基礎的な文法について参照するには、 京都大学の冨田博之先生 テキスト がとても有用です。 なお、 g77はGCC 3.4.xまでで,GCC 3.5以降はg95 (gfortran)をサポートするとのこと です。 最近(2016年)は、Ubuntu Linuxなどでも gfortranが普通に使えるように なっているので、以下は、gfortran用に書き換えていきます。

端末の起動

まず、 UNIXコマンドを使うため、 端末(またはターミナルまたはTerminal)を開きます。 情報統括センターのUbuntu Linuxの場合、 画面左のアイコンの並んでいるランチャーの一番上にある検索ボタンを クリックして検索欄が出てきたら、 terminal と打ち込んで、 端末(またはターミナルまたはTerminal)が出てきたら、 それをクリックして起動します。 端末を終了するときは exit と打ってエンターを押します。

コンパイルと実行

では、まず「あいうえお」と画面に表示させるだけのプログラムを 作ってみましょう。 geditを使う場合は、gedit aiueo.f90 & と&をつけて起動して、 (viの場合は、vi aiueo.f90 みたいに起動して) テキストの参照すべき箇所は、 1.3.1. プログラム単位2.1.2. 文字列の出力です。


       print *,"あいうえお"
       end

と書き込んで、保存しましょう (viの場合は、ZZ または、:wq で保存)。 さて、aiueo.f90 は単なるテキストファイルなので、 このままでは、コンピューターが aiueo.f90 に書かれた プログラムの内容を理解して実行することはできません。 これを実行できるようにするには、 aiueo.f90 に書かれたプログラムを、 コンピューターが理解できる機械語に翻訳する必要があります。 人間が理解できるプログラム言語で書いたテキストファイル (ソースコード)を コンピューターが理解できる機械語に翻訳する操作のことを コンパイルといいます。

aiueo.f90 をコンパイルするには、

gfortran aiueo.f90 -o aiueo 

と打ちます(書く順番は自由です)。 プログラムに(致命的な)間違いがあると、ここでエラーメッセージが表示されますが、 特に大きな間違いがなければ、 コンパイルが終了してコマンドプロンプトが表示されます。 ls と打ってみると、aiueo という実行ファイルができているのが確認できます (緑色のファイルは、実行ファイルであることを示しています。 尚、gfortran aiueo.f90 とだけ打ってコンパイルした場合は、 a.out という実行ファイルができあがります。 このやり方だと、違うプログラムをコンパイルするたびに、 a.out が上書きされてしまうので、 -o aiueo というオプションを付けて、実行ファイルが aiueo というファイルに出力されるようにしている訳です)。 ./aiueo と打つと、 aiueo が実行されて「あいうえお」と表示されます。 ./ は、「今 コマンドラインで作業しているカレントディレクトリーの中の」 という意味です。 コマンドラインから実行ファイルを実行するときは、 その実行ファイルのパス(パソコンの中のアドレス)付きで実行する必要があります。 だから、今、/home/suzuki/prog の中で実行ファイルaiueoを作ったのなら、 /home/suzuki/prog/aiueo として実行するのと同じです (環境によっては、ユーザーディレクトリーにパスを切っている設定の場合は、 パスなしで aiueo とだけ打ち込んでも実行できるようになっている こともあります)。

プログラムの強制終了

 プログラムの実行中にプログラムを強制終了させたい場合は、 Cntlキーを押しながら c を押して下さい。

先頭目次
型宣言、データ入力、代入

 長方形の短辺と長辺を入力すると長方形の面積を表示するプログラムを 作ってみましょう。例えば、


       implicit none
       real :: tanpen, tyouhen, menseki
         print *,"長方形の短辺を入力して下さい"
          read *,tanpen
         print *,"長方形の長辺を入力して下さい"
          read *,tyouhen
         menseki=tyouhen*tanpen
         print *,"長方形の面積は:",menseki
       end

 プログラムの中身を少し説明します。

       implicit none

この宣言をしておくと、暗黙の型宣言(先頭文字がi-nの変数が整数型でそれ以外は実数型)が 無効になるので、うっかり宣言していない変数を書いたりすると、 コンパイル時にエラーが出て教えてくれるようになります。

       real :: tanpen, tyouhen, menseki 

これは、tanpen, tyouhen, menseki という3つの変数を実数として使うことを 宣言しています テキスト参照箇所: 4.1.1. 基本的な型宣言)。

       print *,"長方形の短辺を入力して下さい" 

これは、「長方形の短辺を入力して下さい」と画面表示するということです。

        read *,tanpen

これは、キーボードから入力した数字を tanpen に入れるという ことです テキスト参照箇所: 7.2.1. 入出力文)。

        menseki=tyouhen*tanpen 

これは、tyouhen と tanpen を掛け算した数値を menseki に代入する ということです。右辺を計算した数値を左辺に代入します。 例えば、x を x+1 と置き換える場合は、x=x+1 のように書きます ( x+1=x みたいに逆に書かないように!  テキスト参照箇所: 2.1. 算術演算)。

課題1: menseki1.f90 を参考にして、 三角形・台形などの幾何学図形の面積や、 円錐・球などの立体の体積を求めるプログラムを作りなさい (長方形の面積はここに書いてあるのでダメ)。

先頭目次

Fortranで簡単なプログラムを作成(2回目)

IF構文(場合分け)、DO構文(繰り返し)

 ただ長方形の面積を求めるだけでは面白くないので、 短辺を長辺より長く入れたら警告を表示して計算してくれないプログラム (menseki2.f)を作ってみましょう。


       implicit none
       real :: tanpen, tyouhen, menseki
         print *,"長方形の短辺を入力して下さい"
          read *,tanpen
         print *,"長方形の長辺を入力して下さい"
          read *,tyouhen
        if(tanpen > tyouhen) then
          print *,"短辺が長辺より長いので計算しません"
        else
         menseki=tyouhen*tanpen
         print *,"長方形の面積は:",menseki
        end if
       end

ここで登場する

        if(条件A) then
          操作B
        else
          操作C
        end if

という構文は、条件Aを満たす場合は、操作Bを実行し、 満たさない場合は操作Cを実行しなさいということ テキスト参照箇所: 3.2. ブロックIF構文)。

比較演算子など
a==baとbが等しいならば
a/=baとbが等しくないならば
a > baがbより大きいならば
a >= baがb以上ならば
a < baがbより小さいならば
a <= baがb以下ならば

複数の条件を「かつ」や「または」で組み合わせたいときは、 ((条件1).and.(条件2)) や ((条件1).or.(条件2)) を使う。 例えば、 「a<x かつ x<b」 なら 「if((a<x).and.(x<b))」と書くし、 「x<a または b<x」 なら 「if((x<a).or.(b<x))」 と書く。

 短辺を長辺より長く入れたら計算しないで終わってしまうのでは 今ひとつ面白みがないので、 短辺を長辺より短く入れてくれるまでデータ入力を繰り返す プログラム(menseki3.f)を作ってみましょう。


       implicit none
       real :: tanpen, tyouhen, menseki
        do
          print *,"長方形の短辺を入力して下さい"
           read *,tanpen
          print *,"長方形の長辺を入力して下さい"
           read *,tyouhen
         if(tanpen < tyouhen) exit
          print *,"短辺は長辺より短くして下さい"
        end do
         menseki=tyouhen*tanpen
         print *,"長方形の面積は:",menseki
       end

ここで登場する

       do
         操作A
        if(条件B) exit
         操作C
       end do

という構文は、 条件B が満たされない限りはいつまでも操作A, 操作C を繰り返すということ テキスト参照箇所: 5.1. 決まった回数の単純な繰り返し5.3. 途中で抜ける)。

課題2: menseki3.f90 を参考にして、 ある条件 (例えば「体積が1000以上になる」とか) を満たすまでデータ入力を繰り返し、 三角形・台形などの幾何学図形の面積や、 円錐・球などの立体の体積を求めるプログラムを作りなさい (長方形の面積はここに書いてあるのでダメ)。

先頭目次Fortran目次

Fortranで簡単なプログラムを作成(3回目)

配列

 まあ、1次元配列ぐらいは使ってみましょうか。 クラスの一人一人の試験の点数を読み込んで、 平均点と不合格者(60点未満の人)の番号を出力するプログラムを作ってみましょう。


       implicit none            ! 暗黙の型宣言を無効にする
          real :: tensuu(100)   ! 点数を入れる実数形の1次元配列
       integer :: i,ninzuu      ! 繰り返しステップ数、人数
          real :: goukei        ! 全員の点数の合計
! データ入力
        read *, ninzuu
         do i=1,ninzuu
            read *, tensuu(i)
         end do
! 合計点の計算
         goukei=0.
         do i=1,ninzuu
            goukei=goukei+tensuu(i)
         end do
! 合計点を人数で割って平均点を出す
           print *,"平均点は:",goukei/ninzuu
! 不合格者番号の表示
         do i=1,ninzuu
            if(tensuu(i) < 60. ) then
               print *,"不合格者番号:",i
            end if
         end do
       end

まずはプログラムについて少々。

	  real :: tensuu(100) 

 これは tensuu(1)〜tensuu(100) までの 100個の成分を取り得る 1次元配列(まあ1次元だからベクトルと言ってもいいけど)を宣言している テキスト参照箇所: 6.1. 1次元配列)。

              ! 点数を入れる実数形の1次元配列

! (半角文字のびっくりマーク)を書いたところから改行までは コメントとみなされるので注釈とかを書ける テキスト参照箇所: 1.2.2 自由形式)。 但し、6桁目(2行をつなぐ際に&を書く桁)には ! は書けない。

       integer :: ninnzuu

人数を入れる変数を整数形で宣言する。 数を数えたりする場合の数字は整数形にして、 実数形とは区別して扱う テキスト参照箇所: 4.1. 実数型と整数型)。

         do i=1,ninzuu
            read *, tensuu(i)
         end do

まず、i=1 のとき tensuu(1) を読み込み、次に i=2 のとき tensuu(2) を 読み込み……と続けていって、最後に i=ninzuu となり tensuu(ninzuu) を 読み込む テキスト参照箇所: 5.1. 決まった回数の単純な繰り返し)。

         do i=1,ninzuu
            goukei=goukei+tensuu(i)
         end do

まず、i=1 のとき goukei=0+tensuu(1) つまり goukei=tensuu(1) となる。 i=2 のとき goukei=goukei+tensuu(2) つまり goukei=tensuu(1)+tensuu(2) となる。 ……を続けていって、i=ninzuu のとき goukei=goukei+tensuu(ninzuu) つまり goukei=tensuu(1)+tensuu(2)+.....+tensuu(ninzuu) となる テキスト参照箇所: 5.1. 決まった回数の単純な繰り返し)。

           print *,"平均点は:",goukei/ninzuu

実数形を整数形で割る場合は答えは実数形になると思うので、 特に形を一致させる必要はないと思いますが、 ninzuu を実数形にする必要のある場合は、real(ninzuu)のように すると実数形に変換されます。 例えば、 整数形の10を整数形の3で割ると、答えが整数形の3になったりするので、 実数として割られることを期待する変数は real で実数形に変換する 必要があります。 逆に x**3 などを計算する場合、3 が整数であれば、 コンピューターは素直に x*x*x を計算してくれますが、 x**3. などと書いてしまうと、コンピューターは (x**2.999999999 を計算する場合と同じように対数を取ったりして?) すごく難しい計算をしてしまうので、計算時間の無駄になってしまいます。 (テキスト参照箇所: 4.1.3. 型の変換 )。

 さて、このプログラムを実行すると、 最初に人数の入力を求められて、その後、 人数ぶんの点数の入力を求められるが、 これをいちいちキーボードから打ち込むのではめんどくさいし、 間違いが起きやすい。 こういう場合は、入力データをファイルにして入力してみましょう。 まず、vi tensuu.d として、

10
95.
20.
65.
70.
50.
0.
80.
100.
45
60

みたいな入力データを作って保存しましょう (上の例は、1行目に人数の10人が、2行目から11行目までに 10人ぶんの点数が並んでいる)。 gfortran heikin.f90 -o heikin でコンパイルしたら、 ./heikin < tensuu.d のように実行してみて下さい。 ファイルから入力されて実行されると思います。 画面に表示される実行結果を kekka.out というファイルに出力 したい場合は、./heikin < tensuu.d > kekka.out のように 打ちます。

先頭目次

課題3: heikin.f90 を、 最高点の人の番号と最低点の人の番号も出力できるように 改造しなさい。 (標準偏差も出すとか、他にも機能を加えたい人は加えて構いません)。

先頭目次