コンテンツに飛ぶ | ナビゲーションに飛ぶ

  • 日本語
  • English
 

f95

Fortran95
<Fortran95 対応について>                   本体へ戻る
                        1999年11月 著者
                 
1998年10月にJIS規格の改訂が行われ,現在の規格は「Fortran95」となっているが,
教科書では以下の理由により「Fortran90」対応にしてある。

 ・当時流通していたコンパイラは,まだ「90」対応のものが多く見かけられたこと。
 ・「77」から「90」への抜本的改訂に比べて,今回の「95」への改訂は僅少であり,
  主たる追加機能(FORALL文など)は,初等プログラミング教育では割愛しても
  差し支えないと判断したこと。
 ・「90」で廃止予定とされていた機能については,全て割愛したこと。

(参考)
1.「95」での主たる追加機能
 (1) FORALL文,FORALL構文 (下に解説あり)
 (2) ポインタの初期化
 (3) 構造体の暗黙的初期値設定

2.「90」からの廃止事項(教科書では既に割愛または廃止予定としてある)
 (1) 実数型,倍精度実数型のDO制御変数(p.42)
 (2) IFブロックの外部からENDIF文への飛び越し
 (3) PAUSE文
 (4) ASSIGN文,割り当て型GOTO文,割り当て型FORMAT文
 (5) H型文字編集記述子(p.160)

3.廃止予定事項(次期改正時に廃止が予定されているもの)
 (1) 算術IF文(したがって従来の『論理IF文』は単に『IF文』と呼ばれる。)
 (2) DOループ端末文の共有,END DOおよびCONTINUE以外の端末文(p.42)
 (3) 戻り先指定付きRETURN文(p.96)
 (4) 計算型GOTO文
 *(5) 文関数(p.6,p.106)
 *(6) 実行文中のDATA文(文の位置)(p.13)
 *(7) 固定形式(p.10)
 *(8)「CHRACTER*長さ」形式の文字型宣言(p.32,p.77)
  (9) 文字長引継ぎ文字関数

 * 印 :教科書に記述されているもの。このうち特に「文関数」は初心者には等号=の
意味が代入文の等号と混同されやすいため,授業では割愛されてもかまわないであろう。

==============================================================================

「FORALL文,FORALL構文」(Fortran95追加機能)

例1 多次元配列の値の代入

             INTEGER :: mat(0:7,0:7)
             FORALL(i=0:7, j=0:7) mat(i,j) = 8*i + j

  または

             FORALL(i=0:7,j=0:7)
                mat(i,j) = 8*i + j
             END FORALL

  この例は

             DO i = 0, 7
             DO j = 0, 7
                mat(i,j) = 8*i + j
             END DO
             END DO

  と結果は同じである。
  

例2 WHERE文の代わり

             REAL :: a(0:n)

  のとき

             WHERE(a>0.0)  a = SQRT(a)

  は

             FORALL(i=0:n, a(i)>0.0) a(i) = SQRT(a(i))

  と同じ。


例3 並列処理(DO文との差異)に注意:

             INTEGER :: oct(0:7)=(/0,1,2,3,4,5,6,7/)

  のとき

             FORALL(i=1:7) oct(i) = oct(i-1)

  または

             FORALL(i=1:7)
                oct(i) = oct(i-1)
             END FORALL

  は,配列演算式

             oct(1:7) = oct(0:6)

  と同じく並列処理(同時処理)され,配列は (/0,0,1,2,3,4,5,6/) となる。

  これに対して DO構文

             DO i = 1, 7
                oct(i) = oct(i-1)
             END DO

  では順次処理が行われて (/0,0,0,0,0,0,0,0/) となり,結果は全く異なる。

  特に,FORALL構文中に複数の実行文が書かれている場合には,注意を要する:

             INTEGER :: oct(0:8)=(/0,1,2,3,4,5,6,7,8/), cto(0:7)
             FORALL(i=0:7)
                oct(i) = 0
                cto(i) = oct(i+1)
             END FORALL

  においては,構文中の1行目の代入文がすべてのiについて処理し終わった
  あとの結果を用いて2行目の代入文が実行されるため,ctoの要素は全て0
  となる。すなわち,以下の2行の配列演算式

             oct(0:7) = 0
             cto(0:7) = oct(1:8)

  を書くのと同じであり,DO文で

             DO i = 0, 7
                oct(i) = 0
                cto(i) = oct(i+1)
             END DO

  と書く場合とは全く異なる結果になる。前者では cto は (/0,0,0,0,0,0,0,8/),
  後者では (/1,2,3,4,5,6,7,8/) となる。

  ここまで来ると,よほど習熟していない限りアルゴリズムの深刻なミスを
  冒す危険がある。生兵法は怪我のもと!

本体へ戻る