FORTRAN77規格について

FORTRANは1950年代から使われている, もっとも古い高級言語である. 1966年に FORTRAN66 として規格が定められ, その後,1978年に全面的に改訂されて FORTRAN77 となった.

このように,長い歴史を持つ言語だけに, FORTRANで書かれたライブラリーは膨大な量にのぼる. 反面,C言語など新しい言語が数多く存在する現在では, 古い歴史を引きずった堅い(融通の効かない)言語という印象も免れない. しかしながら, FORTRANには科学計算用の言語として, 他の言語にはない使いやすさがある. 単に「蓄積が大きい」というだけでなく, この「使いやすさ」こそ, FORTRANが30年以上も使い続けられてきた真の理由である.

FORTRANに限らず,どんな言語でもそれを使いこなすのは, なかなか大変である. 幸にも,FORTRAN の仕様は比較的小さい(文法書が薄い)ので 学習は容易なほうであるが, それでもFORTRANを``極める''のは容易なことではない. MATH1を含む地球流体電脳ライブラリでも, 入門書に書いてない「奥義」をかなり使っている. もちろん, これらの知識がなくても電脳ライブラリを使うことは可能である. しかし,電脳ライブラリをよりよく理解し上手に使いこなすためには 是非とも知っておいていただきたい. また, これらの知識は応用範囲が広いので, 一般のFORTRANプログラムを書く際にも, きっと役にたつはずである.

FORTRANの方言

計算機言語には各国の標準機関(日本ではJIS) 及び国際標準機関 (ISO) により 定められた規格がある. FORTRAN も例外ではなく, という言語規格があるが,実質的には全て同じもので, いわゆる FORTRAN77 の規格である.

言語規格というのは「日本語の文法」の様なもので, 計算機に自分が意図した動作をさせるためには これをよく知っていなければならない. これは,当り前のようで,意外に.く.せ.も.のである. なぜならば,普通,多くの人々は FORTRAN を勉強する時, 英語の勉強のように,文法を厳しく教わりながら勉強 するわけではないからである. どちらかというと,日本語を覚えたときと同じ様に, 「見よう見まね」または「試行錯誤」により FORTRANを勉強するのが普通である. そうなると,多くの人が生まれた土地の方言を, 方言と気づかずに覚えてしまうのと同じ様に, 特定の計算機の特定のコンパイラだけが解釈できるプログラムを 平気で書いてしまうことになる.

FORTRAN コンパイラは通常, 標準語としてのFORTRAN77規格 + α の機能を持っている. この + α の部分は,拡張機能と呼ばれ, このような拡張機能を持つコンパイラは FORTRAN77 上位互換(アッパーコンパチ)コンパイラと呼ばれる. これは,標準語だけで書かれたプログラムでも, + α の機能を使ったプログラムも, どちらもコンパイルできるという意味では コンパイラの「機能が高い」のであるが, 逆に+αの機能を使ったプログラムは, そのコンパイラでないとコンパイルできないことになる. したがって,我々は+αの部分を「方言」と呼ぶ.

日常会話の中では,方言は特に問題にならず, むしろ標準語では表現できないニュアンスまで 伝えることができて便利である場合が多い. これは,方言が標準語の拡張機能として働いているためであるが, ビジネス上の会話で方言を使うと,とんでもない結果をもたらす. 多くの人は「明日, 東京にいかずー」という約束をしたら, 明日, 東京にいくべきか否か迷うに違いない. (これは中部地方の方言で,東京にいこう,という意味である)

これと同じ様に,FORTRANの「方言」は特定の計算機を使いこなすには 便利な場合も多いが, むやみに使うと非常に危険である. しかし,生まれた土地を離れたことがないと, 自分の言葉が方言かどうかわからないのと同じ様に, 特定の計算機しか使ったことがないと, 正確なFORTRANの文法を身につけるのは難しい. なぜなら, いつも使っているFORTRAN77のコンパイラがちゃんとコンパイルしてくれれば, そのプログラムはFORTRAN77規格に準拠したプログラムであると 思ってしまうからである. しかし,これは明かな間違いである. どんなコンパイラでも大なり小なり「方言」を持っており, その「方言」を使ったプログラムは, たとえ,FORTRAN77規格のコンパイラでコンパイルできたとしても, FORTRAN77規格準拠のプログラムではない.

そこで,FORTRANで何とかプログラムが書けるようになった初心者も, この道10年のベテランも, 市販の文法書以外に「岩波FORTRAN辞典」を 座右におかれることを強くお勧めする. これは単なる文法書ではなく, 規格が意味するところや,歴史的背景などが解説してあって, 辞典としてだけでなく,読物としても面白い書物である.

電脳ライブラリはいくつかの例外を除いて, 極力この「方言」を避けて書いてある. どうしても「方言」使わなければならないようなところは, 直接「方言」を使わず「電脳標準語」を定義して, 各プログラムの中では「電脳標準語」を使うようにしている.

例えば,SYSLIB の中の MSGDMP はエラーを検出したとき, システムに依存したエラー処理をおこなって (たとえば,エラーのトレースバック情報を出力して) プログラムを強制終了する OSABRT というサブルーチンを呼ぶ. 各コンパイラは必ずといってよいほど, この種のサブルーチンを「方言」として持っており, OSABRT は単にそのコンパイラ固有のサブルーチン(方言)を 呼んでいるだけである. しかし,その「方言」を使わず, 「電脳標準語」である OSABRT を使って他のサブルーチンを書いておけば, OSABRT を各コンパイラ用に書きなおすだけで, そのようなプログラム全てを移植できることになる.

この移植のしやすさ(可搬性)こそ電脳ライブラリの最大の特徴であり, ライブラリ開発者が最も苦労した部分でもある. この特徴を最大限に生かすためにも, FORTRANの文法をよく理解して, 不必要な「方言」を使わないよう心がけて欲しい.

以下の節では不必要な方言を避けるために知っておくべき知識,知っていると 便利なことがら,そして,プログラミング上の盲点となるような落し穴につい て多少の解説をしておく.

不定の概念

FORTRAN 規格の基本的な概念に「不定」という概念がある. これは最も重要な概念の一つでありながら, 最もわかりにくい概念でもある. FORTRANを勉強したことのある人ならば, 文法書の中の
○○の時, 変数××は不定となる.
という記述を見て, 首をかしげた経験が1度はあると思う. 最初にこれを読むと,「××に乱数が代入される」とか 「数値がメモリ上から消滅する」ということを想像してしまうが, 決してそういう意味ではない. 大抵の場合,○○の時, ××がどうなるか, コンパイラはちゃんと知っている.

この奇怪な文章を理解するには, FORTRANの規格の文章が誰に対する文章であるかということを, よく理解しておく必要がある. FORTRAN規格というのは,我々プログラマに対する文章であると同時に, FORTRANコンパイラをつくる人に対する文章でもある. したがって,この文章は2通りに翻訳できるように書いてあるのである. 上記の文章を, コンパイラをつくる人に対する文章に翻訳すれば,

○○の時, 変数××が占めていた記憶領域をどのように使ってもよい.
ということになり, 我々プログラマに対しては,
コンパイラをつくる人に,上のように言ってしまったので, ××がどうなるかわからない.
ということになる.

もし,この文章をコンパイラを「作った人」から「使う人」へのメッセージだと 解釈してしまうと, 「自分で作っておきながら,わからない,どういうことだ」 と言いたくなってしまう. 特に,コンパイラに付属の文法書を読んでいると, そのような錯覚に落ちいりやすいが, FORTRANの文法書とはあくまでも,

コンパイラを作る人と,それを使う人の .両.者.の.責.任.関.係を明確にするための法律
なのである.

「不定」とは逆に, 規格によって値が保証されている状態を「確定」という. 規格上,プログラムの中で引用できる変数は「確定」された変数だけである. 以下,変数が「不定」となる例である.

ENTRY文

FORTRANでサブルーチンを書く時, いろいろな場合を想定して, なるべく汎用的なサブルーチンにしようとすると, 引数がどんどん増えて困ることがある. 大事な引数は2-3個なのに, どうでもよいような引数がずらずらと並んでいると, それだけで CALL .... と書く手が重くなってくる.

そのような時にENTRY文を使うと解決できる場合がある. ENTRY文とは,サブルーチンの途中から実行を始めるための文である.

*−−−−−- main program −−−−−-
      REAL X(10)
      .......
      CALL TABLE(X, 10)
      .......
      END
*−−−−−−−−−−−−−−−-
      SUBROUTINE TABLE(X,N)
      REAL       X(N)
      DATA       IOU /6/
      SAVE

WRITE(IOU,'(10F12.4)') X RETURN

ENTRY IOUSET(IOU0) IOU = IOU0 RETURN END

このサブルーチンTABLEは 1次元配列Xを出力するものであるが, TABLEだけを呼べば, DATA文で指定されたIOUの機番(6)に出力される. ファイルなど別の機番に出力させたい場合は, TABLE を呼ぶ前にIOUSET を呼んで, IOUを書き換えておけばよい. つまり,1つのサブルーチンに, 印刷すべき変数だけを与える入口と, その他のパラメータを設定する入口の,2つの入口を作るわけである.

ここで,注意すべきことはSUBROUTINE文またはENTRY文で指定された引数は, そのSUBROUTINE文またはENTRY文から入った時でないと使えないことである. 例えば,このプログラムのENTRY文から入った時(IOUSETが呼ばれた時), 変数N を引用することはできない. 同じように, TABLEが呼ばれた時にIOU0を引用することはできないので, IOUSETが呼ばれたときにIOUに代入しておかなければならない. また,このようなプログラムでもSAVE文とDATA文は不可欠である.

GLpGET/GLpSETの構造

電脳ライブラリの「パラメータ掲示版」である SYSLIB の GLpGET/GLpSETは, 毎回指定する必要のないパラメータをうまく隠蔽して見えないようにしておく という前述のテクニックを極限にまで利用したライブラリなのである. GLpGET/GLpSETは他のプログラムにパラメータを渡すだけで, あとは何もしない. その構造は, 以下のようになっている(実際のソースより簡略化されている).

(注: Ver.5 の電脳ライブラリでは,実行時パラメータによって 内部変数への介入が可能になったため GLpGET/GLpSETは 内部でさらに下請けルーチンを呼ぶようになった. 以下では,Ver.4 の電脳ライブラリにおける GLpGET/GLpSETを 用いて説明をおこなう. Ver.5 の下請けルーチンの構造は,基本的に Ver.4 の GLpGET/GLpSETと同じである.)

*−−−−−−−−−−−−−−−−−−−−−−−-
*     GLPGET / GLPSET
*−−−−−−−−−−−−−−−−−−−−−−−-
      SUBROUTINE GLPGET(CP,IPARA)
      CHARACTER CP*(*)
      PARAMETER (NPARA=17)
      INTEGER   IX(NPARA)
      REAL      RX(NPARA)
      LOGICAL   LX(NPARA)
      CHARACTER CPARA(NPARA)*8
      EQUIVALENCE (IX,RX,LX)
      SAVE
      DATA CPARA( 1)/'NBITSPW '/, IX( 1)/32/
      ........ 
      DATA CPARA(12)/'LMISS   '/, LX(12)/.FALSE./
      DATA CPARA(13)/'IMISS   '/, IX(13)/999/
      DATA CPARA(14)/'RMISS   '/, RX(14)/999.0/
      ........
      DO 10 N=1,NPARA
        IF (CP.EQ.CPARA(N)) THEN
          IPARA=IX(N)
          RETURN
        END IF
   10 CONTINUE
      エラー処理
      STOP
*−−−−−−−−−−−−−−−−−−−−−−−-
      ENTRY GLPSET(CP,IPARA)
      DO 15 N=1,NPARA
        IF (CP.EQ.CPARA(N)) THEN
          IX(N)=IPARA
          RETURN
        END IF
   15 CONTINUE
      エラー処理
      STOP
      END

ここで,CPARAという文字変数にパラメータ名が登録されており, その名前に対応した値が IX, RX, LX という変数に入っている. (これら3つの変数はEQUIVALENCE文により結合されているので, 実際には1つの記憶領域しか持たない)

さて,IFALIBの関数IMAXは,欠損値以外の最大値を求めるものであるが, IMAXは欠損値を示す整数値を引数から得る代りに,

      CALL GLPGET('IMISS', IMISS)

という文を実行する. この時, GLPGET では,CPARAの中から'IMISS'という名前を探して (24-29行目)その名前に対応する値IMISSとして返す. この時返される値は,DATA文によって指定されているが, 必要であれば,あらかじめこれらの値をGLISETで変更しておくこともできる.

この方法が前の節の方法 (各プログラムがIMISS 設定用のENTRYを持つ方法) より優れている点は, GLPGETが持つ情報を複数のサブルーチンから参照できることである. 例えば,欠損値を示す値は何も初期値としては999が与えられているが, 999がデータ範囲に入っているような場合には, これを変更しておかなければならない. そのような時にでも GLPSET を一度呼ぶだけで, 欠損値処理をする全てのサブルーチンの動作を制御することが可能になる.

文字型変数とその他の変数の違い

前節では実変数,整変数,論理変数を混同した書き方をしても, 大きな問題にならなかった. これは,FORTRAN規格により,これら3つの型のデータが全て 「1数値記憶単位を占める」と規定されているからである. これに対して,文字型のデータは1文字が「1文字記憶単位を占める」 と規定されている. 多くの処理系においては「1数値記憶単位」は32ビットの「1ワード」に対応し, 「1文字記憶単位」は8ビットの「1バイト」に対応するが, 規格の中で具体的な長さは規定されていない. したがって,文字型とその他の変数をEQUIVALENCE文で結合したりすると, 規格上,「数値記憶単位」が「文字記憶単位」のいくつ分に 相当するかわからないため, そのような結合は禁じられている.

さらに,これは規格上の話だけではなく, 上記のような1ワードが4バイトに相当する標準的な処理系で, ユーザーが「数値記憶単位」と「文字記憶単位」の対応をよく考えた上で 結合したとしても実害が生じる場合がある. これは, 文字型変数が文字単位で任意の長さがとれることから, 文字型変数の扱い方が,それ以外の変数(実数,整数,論理変数)と 大きく異なる場合があるからである. 特にサブルーチンの引数の渡し方が異なる場合が多い.

もともとFORTRAN66の規格には文字型変数はなく, 文字を扱う場合にはキャラクターコード列(整数)として扱われていた (4文字を1つの整数として扱っていた). そのため4文字単位の長さの文字列しか扱えず不便であったが, FORTRAN77から文字型変数として正式に認知されるようになった. これに伴って,任意の長さの文字列が扱えるようになるなど, 文字の扱いが非常に楽になった反面, 上記のような制約も増えた. もっとも,かなり多くのコンパイラでは文字型とそれ以外の変数の 結合が可能であるが, これも「方言」の一つである.

実際の観測データなどを扱う分野では, 文字と数字が混在したデータを扱うことも少なくないので, 伝統的にこのようなEQUIVALENCE文を使っている場合もあるが, 実際にこのような結合ができないコンパイラもあるので, 注意が必要である.

さらに,文字型変数は他の型の変数と違って,以下の例のように, 同じ文字要素を式の右辺と左辺に書く(3行目)ことが禁じられている.

      CHARACTER*12 CX
      CX = 'DENNOU'
      CX = CX(1:6)//'DENNOU'

文字以外の変数では,同様のことが許されているので, つい,このような代入文を書いてしまいそうになるが, このような場合には,

      CHARACTER*12 CX
      CX = 'DENNOU'
      CX(7:12) = 'DENNOU'

とすれば,問題はない.

フォーマットの動的変更

FORMAT文を用いてWRITE文などで出力する書式を指定する場合, 書式の中に変数が使えないため, 「プログラムの中で必要な桁数を判断して, 出力する桁数を変える」という様な芸当ができない. このあたりが,古い言語の堅さの1つなのであるが, 「だからFORTRANはきらいだ」という前に,以下の説明を読んで欲しい.

FORTRAN77では WRITE文の書式識別子にFORMAT文の文番号ではなく, 以下のように,文字.変.数を指定することができる. この機能を使えば,書式の動的な変更が可能になる.

      CHARACTER CFMT*12
      ...
      CFMT = '(T12, F5.2)'
      WRITE(6,CFMT) X
      ...

この例では,文字変数CFMTに定数を代入しているだけなので, 動的に書式を変更するようにはなっていないが, CFMTは.変.数であるから, プログラムの中で変更するのは容易である.

桁数などの数値変数を文字変数に書き込むには, やはりWRITE文を使う. WRITE文の出力機番を書くところに文字変数を書くと, その文字変数を``内部ファイル''として, 普通のWRITE文と同じ様に編集,出力ができる.

      CHARACTER CFMT*12
      ...
      CFMT = '(T12, Fx.2)'
      WRITE(CFMT(8:8),'(I1)') N
      WRITE(6,CFMT) X
      ...

この例では,整変数Nを文字変数CFMTの8桁目に書き込み, Xを出力する際の桁数としている. このあたりのテクニックはFORTRAN66の時代には使えなかったので 知らない人も多いが, 知っていると非常に便利である.

多次元配列の記憶順序

FORTRAN77では多次元(7次元まで)の配列を定義できるが, 実際の記憶装置は多次元構造を持っているわけではなく, 1次元的に管理されている. 多次元配列を1次元的に展開する順序は, FORTRAN77の規格で定めてあるので, 多次元配列を1次元配列と結合する (多次元配列に1次元配列の別名を与える) ことが可能である. 例えば

      REAL         X(6), Y(2,3)
      COMPLEX      Z(3)
      EQUIVALENCE (X,Y,Z)

という場合, 変数X, Y, Zはどれも長さが6語(48バイト)の配列で, EQUIVALENCE文により同じ記憶領域を占める. この時, それぞれの変数の並び方は

+----------+----------+----------+----------+----------+----------+
| X(1)     | X(2)     | X(3)     | X(4)     | X(5)     | X(6)     |
|----------|----------|----------|----------|----------|----------|
| Y(1,1)   | Y(2,1)   | Y(1,2)   | Y(2,2)   | Y(1,3)   | Y(2,3)   |
|----------|----------|----------|----------|----------|----------|
| Re(Z(1)) | Im(Z(1)) | Re(Z(2)) | Im(Z(2)) | Re(Z(3)) | Im(Z(3)) |
+----------+----------+----------+----------+----------+----------+

という様に,2次元配列Yは添字の左側の数字から変るように 1次元的に展開される. また,複素数データZは2つの実数が並んだ形で展開される. したがって,X(3) の数値はY(1,2), Re(Z(2)) と 全く同じになる.

この規則は多くのプログラムで積極的に使われており, 多次元配列を1次元配列として扱ったり, 複素数データを実数データを見なして処理したり することが行われている. この規則は,計算機のハードウェアに近い部分の規則なので, 計算機によって異なるように思えるかもしれないが, FORTRAN77規格で定められた「標準語」である.

サブルーチンへのデータ引渡

引数によるデータの引渡では, 前述の配列の記憶順序を意識したテクニックがよく使われる. MATH1のIFALIB, RFALIB, VRALIBなどでは, 1次元配列の要素を飛び飛びに使うための引数(JXなど)が必ずある. これは, 多次元配列を同じサブルーチンまたは関数で処理するためのものである. これらのルーチンの動作を理解するために, 以下のプログラムを見て欲しい.

      REAL X(100)
      ......
      CALL SUM(X, 100, 1, XSUM)
      ......
      END

SUBROUTINE SUM(X, N, JX, XSUM) REAL X(*)

XSUM = 0. DO 100 I=1, JX*(N-1)+1, JX XSUM = XSUM + X(I) 100 CONTINUE END

このサブルーチンは1次元配列Xの和を求めて, XSUMとして返すものである. この同じサブルーチンを2次元配列Y に対して

      REAL Y(10,10) 
      ........
      CALL SUM(Y(2,1), 10, 10, YSUM)
      ......
      END

という様に使うと サブルーチンSUMは,以下のように2次元配列要素Y(2,1)を 先頭とする記憶領域を1次元配列Xに割り当てる.

+------+-------+-----+------+-------+-------+-----+------+-------+-------+-----+
| Y    | Y     | ... | Y    | Y     | Y     | ... | Y    | Y     | Y     | ... |
| (2,1 | (3,1) |     | (10, | (1,2) | (2,2) |     | (10, | (1,3) | (2,3) |     |
| )    |       |     | 1)   |       |       |     | 2)   |       |       |     |
|------|-------|-----|------|-------|-------|-----|------|-------|-------|-----|
| X(1) | X(2)  | ... | X(9) | X(10) | X(11) | ... | X    | X(20) | X(21) | ... |
|      |       |     |      |       |       |     | (19) |       |       |     |
+------+-------+-----+------+-------+-------+-----+------+-------+-------+-----+

その1次元配列Xの要素を10 (JX) 個おきに10個の和をとると, Y(2,1), Y(2,2), ..., Y(2,10) という具合に,二次元配列 Yの第2添字についての和をとることになる.

ここで,サブルーチンの中では配列Xの長さはわからず, 単に,X(1)を先頭とする1つながりのデータとして扱われていることに 注意して欲しい. 配列がサブルーチンに渡されるとき, メインプログラムの配列の中身がサブルーチンの 配列の中身にコピーされるのではなく, メインプログラムの中の配列の番地だけが渡され, サブルーチンの方はその番地を基準に処理を行うのである. このようなことを意識してプログラムを書くと, 少ない引数で柔軟な処理が可能になる.

もう一つの応用例を紹介しよう.

      SUBROUTINE SUM2(X, IMAX, IX, JX, XSUM)
      REAL X(IMAX,JX)

XSUM = 0. DO 100 I=1,IX DO 100 J=1,JY XSUM = XSUM + X(I,J) 100 CONTINUE END

これは2次元配列X(I,J)の一部の和をとるものであるが, これを

      REAL X(102,102)
      ........
      CALL SUM2(X(2,2), 102, 100, 100, XSUM)
      ........

という具合に使うと,102 102の2次元配列のデータのうち, 周辺を残して真中の100 100 の部分, すなわち,(2,2)-(101,101)を対角線とする部分の和をとることができる. MATH1のルーチンで,このような使い方を想定しているものはないが, GRPH2のコンターを描くルーチンなどで応用すると便利である.

なお,サブルーチンに渡すことのできる引数のなかに, 「手続き名」がある. これは,他の引数と異なり「変数」ではないので, 動的な変更はできないが, これが指定できるおかげで,MATH1のVRFNA/VIFNAの様に, サブルーチンを呼ぶ際に使うべき関数を指定することが可能になる. この場合,実引数に指定する手続き名は,サブルーチンを呼ぶ プログラムの中で EXTERNAL文またはINTRINSIC文により 手続き名であることを宣言しておかなければならない.

EXTERNAL文とINTRINSIC文

EXTERNAL文は, そこに指定された関数名が外部関数であることを宣言するものであり, INTRINSIC文は, そこに指定された関数名が組み込み関数であることを宣言するものである. これらは,上記のように関数名をサブルーチンの実引数として使用する時に 必ず必要なものであるが, それ以外も重要な意味がある.

SINCOSのような組み込み関数は, FORTRAN規格によって処理系が用意しなければならないが, FORTRAN規格はさらに処理系が規格外の組み込み関数を用意することを許している. したがって,各処理系はFORTRAN規格に定められた組み込み関数よりも多くの 組み込み関数を持っているのが普通である. そして当然のことながら,それら拡張された組み込み関数の名前に関しては, 処理系によって全く異なる. ということは, FORTRAN規格にない関数名で, EXTERNAL文やINTRINSIC文によって宣言されていない関数名は, 処理系によって組み込み関数として解釈されたり外部関数として解釈されたり することがある.

例えば,自分で外部関数を定義して, それを引用しているつもりでも, たまたまその処理系が同名の組み込み関数を持っていた場合には, ユーザー定義の関数ではなく, 処理系が用意した関数が呼ばれてしまう可能性がある. 関数名の長さは6文字以内と制限されている上, 人間の発想も多様性に限りがあるので, この手の衝突は意外に多い. しかも,この種の原因でプログラムが暴走したりすると, その原因を突き止めるのはかなり難しい. (自分のプログラムそのものには全く誤りがないのだから)

そこで,処理系に依存しないプログラムを書くためには, そのプログラム単位で引用している外部関数名は全て EXTERNAL文に指定することが望ましい. また,FORTRAN規格にない処理系固有の関数を引用している場合には, INTRINSIC文に指定すべきである.

なお,当然のことながら, 電脳ライブラリが用意する関数は全て「外部関数」である. 処理系から見れば電脳ライブラリを含めて全て「ユーザープログラム」 であるから, 自分が書かなかったからといって組み込み関数と混同することのないように 注意されたい.

COMMON文

前述のEQUIVALENCE文が同じプログラムの中の変数を結合させる ものであったのに対し, COMMON文は異なったプログラム単位(サブルーチンなど)の中の 変数同志を結合させるものである.

初期のFORTRANでは引数によるデータの引渡しに時間がかかったため, COMMON文によりメインプログラムから サブルーチンへデータを引き渡す方法が多用された歴史がある. しかし,現在ではデータの引渡しに要する時間は, どちらの方法でもほとんど変らない. それより,COMMON文を使うと, どのサブルーチンで値が代入されているのかわかりにくくなってしまうので, 可読性を高めるという見地から, COMMON文によるサブルーチンへのデータ引渡はお勧めできない.

電脳ライブラリでも余程特殊な理由(内部の作業領域確保など)がない限り, COMMON文は使用していない. 各サブルーチンへのデータの引渡は全て引数を使っている.

その他

その他,FORTRANでプログラムを書く場合の注意を以下に列挙する.


Back to Main


Latex Source


地球流体電脳倶楽部 : 95/6/9 (Version 5.0)

NUMAGUTI Atusi <a1n@gfdl.gov>
Last Modified: Thu Aug 31 13:00:41 EDT 1995