FORTRAN
出典: フリー百科事典『ウィキペディア(Wikipedia)』
Fortran(フォートラン、FORmula TRANslationの略)は、1954年にIBMのジョン・バッカスによって考案された、コンピュータにおける史上最初の高水準記述言語である。IBM 704向けに最初に作成された。
科学技術計算に向いた、逐次型の手続き型言語である。2006年現在でも使われ続けられており、その仕様は初期の頃と比べればかなり拡張されたものとなってきている(初期の頃は、変数名が大文字6文字までで、動的な記憶領域の確保ができないなどの制約があった)。
尚、大文字でFORTRANと表記した場合、FORTRAN 77以前のFORTRANを指し、Fortranと表記した場合、Fortran 90または95を指すことがある。
目次 |
[編集] FORTRANの特徴
ここでは、広く使われていたFORTRAN 77までのプログラミング言語の特徴について概要を記す。
- 数式を簡便に書ける
- ほぼ数学の数式通りに計算式を記述できる。
- 出力が容易
- スタック指向/構造化指向の言語ではない
- COMMON文、BLOCK DATA文やSAVE文(FORTRAN 77)など、データを固定的に割り当てることを前提としている。
- 固定形式の書式である
- 記述方法がカラム位置で決まっている(一部の実装では拡張されている)
[編集] 初期のFORTRAN
初期のFORTRANは、IBM 704計算機用に作られ、4つのタイプがあった。
- FORTRAN I
- 最も基本的なFORTRAN
- FORTRAN II
- FORTRAN I に副プログラム呼び出しの機能を付加したもの。
- FORTRAN III
- FORTRAN II に若干の改良を行なったもの。bool演算機能(ビット演算機能)があった。
- FORTRAN IV
[編集] 言語仕様
Fortranの言語仕様は、年代によってかなり変化して来ている。他のプログラミング言語で実装された構造化プログラミングの機能などがどんどん取り入れられて来ているからである。
[編集] FORTRAN 66
FORTRAN 66の言語仕様はおおよそ下記のとおり。
[編集] 利用できる文字
- 英数字
- 特殊文字(空白、=、+、-、*、/、(、)、,、.、'、:、;、&、%、$、#、"、@)
[編集] プログラムの書式
プログラムは以下の形式で記述する。もともとパンチカードに書くことを前提としていたので、1行は80文字で構成されていた。行の左端からの文字位置を桁(けた)またはカラムと呼んだ。
- 1~5桁目
- 行番号を書く。1カラム目にCを書くとその行はコメント行になる。
- 6桁目
- 継続行であるときはここに任意の文字(空白又は0以外)を書く
- 7~72桁目
- 本文を書く
- 73~80桁目
- シーケンシャル番号を書く(行を識別するための番号、本文には影響しない)
[編集] 数など
以下の数を扱える。
- 整数(範囲は機種依存、4バイトであればその範囲)
- 単精度実数(整数部+小数部、指数表示可能、精度は機種依存)
- 倍精度実数(単精度の倍の精度を持つ)
- 複素数(単精度または倍精度の実数の組み合わせ。2つの数字を()でくくる)
- 論理型(.TRUE. 又は .FALSE.)
- 文字型(桁数のあとにHを記述し、その後に文字列を記述する。たとえば7HFORTRANなど)
[編集] 変数など
以下の変数宣言を扱える。
[編集] 式
- 算術式(+、-、*、/、**(べき乗))
- 比較(.LT.、.LE.、.GT.、.GE.、.EQ.、.NE.)
- 論理演算(.OR.、.AND.、.NOT.)
[編集] 文
- 実行文
- 代入文
- ASSIGN文
- ASSIGN文で変数に割り当て、次の割当て型GO TO文で割り当てられた文番号にジャンプする
- 制御文
- 入出力文
- READ文
- デバイスと書式を指定し、リストされた変数に値を入力する。
- デバイスは数字、5がカードリーダ入力、6がラインプリンタに定義されていることが多い。書式無しのREAD文もある
- WRITE文
- READ文の逆で、リストされた変数の内容を書式に従って出力する。
- READ文
- 補助入出力文
- 磁気テープ装置の入出力を行ないやすくするために使われるのが基本。
- REWIND文
- 読み出し又は書き込み位置を装置の先頭に位置づける。
- BACKSPACE文
- 1つ前の記録位置に位置づける。
- END FILE文
- ファイルエンドマークを記録する。
- 宣言文
- DATA文
- 初期データを定義する場合に利用する。
- FORMAT文
- 各種の書式を定義する。
- 副プログラム関連
- FUNCTION文
- SUBROUTINE文
- BLOCK DATA文
[編集] 関数
以下の関数を扱える。
- 文関数
- そのプログラム内で有効な関数定義を1行で記述する。
- 組込み関数
- 外部関数
- あらかじめライブラリとして提供されている関数
- 関数副プログラム
- 関数副プログラムは、FUNCTION文で始まるサブルーチンである。
[編集] FORTRAN 77
FORTRAN 77は、FORTRAN 66に、よりプログラムを書きやすくするための文や、動作の明確化をはかっている。FORTRAN 66でのプログラムはほぼそのまま動くようになっている。以下はFORTRAN 77で追加/変更になった点の概要である。
[編集] 数など
[編集] 変数など
変数などについて以下の変更が加えられた。
- IMPLICIT文で、暗黙の型宣言の範囲を変更できるようになった。一部のコンパイラではすでに実装されていたものを仕様化したものである。整数、実数だけではなく、文字型なども指定できる。
- PARAMETER文で、定数に名前を与えられるようになった。FORTRAN 66では、定数は、直接式に書くか、変数を定数代わりに使う方法しかなかった。前者は定数の変更に手間がかかり、後者は定数を変更されてしまう危険性があった。
- 配列の宣言に寸法宣言子を指定できるようになった。FORTRAN 66では配列は1から始まるだけであったが、FORTRAN 77ではマイナスの領域も定義できるようになった。たとえば以下のように定義できる。
- DIMENSION ARRAY (-10:10)
- 部分文字列が利用できるようになった。配列と同じような形で指定できる。
- CHARACTER*4 CHR
- CHR(1:2) = "2B"
- 配列の初期化にDO形並びが利用できるようになった
[編集] 式
[編集] 文
- 宣言文
- IMPLICIT文が追加された
- (関数)副プログラムで、そのプログラム内で定義した変数を、そのプログラム内から抜け出たときも値が不定にならないように、保存するSAVE文が追加された
- 主プログラム名を指定するPROGRAM文が追加された
- 実行文
- IF構造として、IF THEN~ と IF THEN~ELSE~END が利用できるようになった
- 入出力文
- 入出力文の書式が大幅に強化された。以下のパラメータが利用できるようになった。これらを使うことで、入出力操作の柔軟性が向上した。
- UNIT=(装置指定子)
- FMT=(書式指定子)
- ERR=(誤り指定子)
- END=(ファイル終了指定子)
- IOSTAT=(入出力状態指定子)
- REC=(記録指定子)
- 補助入出力文に以下の文が追加された
- OPEN文
- CLOSE文
- INQUIRE文
- 入出力文の書式が大幅に強化された。以下のパラメータが利用できるようになった。これらを使うことで、入出力操作の柔軟性が向上した。
[編集] 関数
以下の関数が追加された
- 文字長(LEN)
- 部分列の位置(INDEX)
- 正接(TAN、DTAN)
- 逆正接(ASIN、DASIN)
- 逆余弦(ACOS、DACOS)
- 逆正接(ATAN、DATAN)
- 双曲線正弦(SINH、DSINH)
- 双曲線余弦(COSH、DCOSH)
- 双曲線正接(TANH、DTANH)
- 文字列の大小比較(LGE、LGT、LLE、LLT)
[編集] Fortran 90
Fortran 90には、他の言語にある、構造化記述を行なうための文法などが取り入れられた。
[編集] 数など
- 文字の種類として、英小文字、アンダースコアを始めいくつかの特殊文字が使えるようになった。
- 定数や変数の精度を指定する種別パラメータが追加された。また、精度を指定したり、精度情報を得るための関数が定義された。
- 暗黙の型宣言を無効にする、IMPLICIT NONE文が定義された。
[編集] 変数など
変数などについて以下の変更が加えられた。
- DIMENSION文やPARAMETER文などで、配列や定数の定義の時に型宣言を同時に行なえるようになった。
- 構造体を定義するための、TYPE文が追加された。
- 動的な配列や変数を定義するALLOCATABLEパラメータが、各定義文に利用できるようになった。また、実際に領域を割り当てるALLOCATE文と、割り当てた領域を開放するDEALLOCATE文が追加された。
[編集] 文
- END文が拡張され、DO文などの終了文に利用できるようになった。
- DOループを途中で飛ばすSKIP文や途中で脱出するEXIT文が追加された。
- 繰返し (ループ) を定義するDO WHILE文が追加された。
- 多重分岐を行なうSELECT CASE~CASE~END CASE文が追加された。
- 仮引数の状態を指定するINTENT文が追加された。
- ポインタ機能を実現するためのPOINTER文、NULLIFY文とTARGET文が追加された。
- 数の比較をC言語と同様に記号で行なえるようになった。但し.NE.は /=と記述する。
- 配列全体に対して操作が行なえるようになった。
- 配列全体に対して比較条件を行なうWHERE文が追加された。
- 内部副プログラムを定義するCONTAINS文が追加された。
- 関数を再帰可能とするRECURSIVEパラメータをSUBROUTINE文、FUNCTION文の前に付けられるようになった。
- モジュールを定義するための、MODULE文、USE文が追加された。
- 利用者定義の操作を作成するためのINTERFACE文が追加された。
- 名前並びを定義するNAMELIST文が追加された。
- 他のソースファイルをマージするINCLUDE文が追加された。
[編集] 仕様の変遷
JISにおける仕様は、以下のように変遷している。
[編集] 初期 (FORTRAN 66)
1967年に、JISとして制定された。この時は、以下の3つの水準ごとに独立したJISが制定された。共通したタイトルは「電子計算機プログラム用言語 FORTRAN」であった。以下に水準間のおおよその違いを記す。
- JIS C 6201(水準7000)
- JIS C 6202(水準5000)
- 変数、配列手続き名は最大6文字
- JIS C 6203(水準3000)
なお、1971、1976年に若干の改訂がなされている。
[編集] FORTRAN 77時代
国際標準化機構 (ISO) は、米国規格協会 (ANSI) の X3J3 が作成した FORTRAN の規格 X3.9-1978 を ISO 1539-1980 として定めた。基本水準 (subset language) と上位水準 (full language) の2種類の水準からなっていた。これを基にして、同じく2水準の JIS C 6201-1982 が制定された。なお、1987年に、JISの分類が変更になり、この規格は JIS X 3001-1982 となった。内容には変更はない。
[編集] Fortran 90時代
FORTRAN 77を基に他の言語の特徴を組み込み、言語仕様を近代化しようとしたが、そのため仕様がなかなか決まらず、1991年に ISO/IEC 1539:1991として制定された。JISではそれを受け、制定された。
[編集] Fortran 95時代
いまでも基本は科学技術用行列演算用途であり、ベクトル型スーパーコンピュータは、Fortranを使ったプログラムで使用することが多い。Fortranは最近の言語Cのように、スタック等を使わず、コンパイル時に静的に記憶領域を確保するのが基本である。そのため、コンパイラはコードを最適化しやすいという利点がある。最近ではスタックや動的な記憶領域が使えるようになっている。
もともとのFORTRANは、字句解析の仕組みが言語CやJavaと大きく異なり、桁位置(行の左端からの文字位置)に依存していた。これを固定プログラム形式という。これは、当時、データの入力にパンチカードを使用していたためである。1桁目から5桁目が文番号で、6桁目が継続行の指定、7桁目から72桁目に文の本体を記述する。73桁目から80桁目は任意に指定可能な、行を識別するための文字列を記述する領域である。
その後、Fortran 90時代には、現在の言語Cのように、桁位置を気にすることない、自由プログラム形式 (文脈自由文法) で記述できるようになった(FORTRAN 77時代でも処理系によっては自由形式で記述できるものもあった)。
[編集] Fortran 2003時代
主な新機能はCとの相互運用とオブジェクト指向です。
[編集] そしてFortran 2008時代
[編集] FORTRANと教育
[編集] 教育向けコンパイラ
FORTRANは、情報処理分野で広く使われていたため、学校や会社の教育(情報処理技術者向け教育)で利用された。教育向けには、より詳細なエラー情報を出すための拡張がWaterloo大学でWATFOR(後にWATFIV)コンパイラとして実装された。この実装は日本の大学でも使われた。また2006年4月にはNAGから教育用FORTRAN統合開発環境FortranBuilderが発売された。
[編集] Fortranとスーパーコンピュータ
Fortranは科学技術計算用の言語なので、スーパーコンピュータでのプログラミング言語としてよく用いられる。したがって、スーパーコンピュータの高速演算機能を有効に使うための工夫がなされた。その1つの例としては、自動ベクトル化機能である。ベクトル型のスーパーコンピュータは、多くの演算を同時に行なうベクトル演算機能がハードウェアで提供されている。この機能を有効に使うために、FortranのDOループをベクトル演算装置で演算させるために、自動的にベクトル命令にする機能が提供された。また、DOループ内のベクトル演算に適さないものをDOループ外に追い出す機能などもある。たとえば、
DO 100 I=1,N A(I) = B(I) * C(I) 100 CONTINUE
のようなDO構文は、ほとんどの場合、1から数個のベクトル演算命令にコンパイルされる。そのほかにもDOループの中にIF文を含むような例、たとえば、
DO 110 I=1,N IF (A(I) .LE. LIMIT) THEN B(I) = A(I) * Z END IF 110 CONTINUE
のようなものもベクトル化できる場合がある。これは、いったんAの各要素がLIMIT以下かどうかを示すマスクベクトルを作成し、Aという配列(=ベクトル)に、変数Zをかけるとき、マスクベクトルを参照してベクトル演算を行なうことによって、DOループをベクトル化する。
このような作業は、すべてコンパイラが行ない、利用者にはできるだけ負担をかけないようにしている。しかし、より高度なベクトル化を行なうために、最適化を行なう支援ツールが用意されている場合もある。
[編集] FORTRANと日本語
コンピュータ上で日本語の文字を扱えるようになると、FORTRANでも日本語を扱う需要が出てきた。そのため、各社(メインフレームを作成していたメーカ)では、独自に言語仕様に日本語の文字を扱えるように拡張した。そのため、各社で日本語の扱い方が異なる事態になった。そこで、JEIDAでは1985年に、JEIDA-42で日本語FORTRANを策定した。
FORTRANで日本語を扱う場合、変数名等には日本語は使えず、文字列や日本語を扱うための専用の型(日本語型)、日本語を入出力するためのFORMAT文の要素の拡張が行なわれた。
[編集] 参考文献
[編集] 暗黙の型宣言による伝統的・慣習上の変数命名規則の誕生
FORTRANのプログラムにおいては、とくに型宣言をしない場合、アルファベットI,J,K,L,M,Nのいずれかで始まる変数名で表される変数は整数型(integer)になり、その他のアルファベット(A~H, O~Z)で始まるものは実数型(real)になる。これが「暗黙の型宣言」といわれるFORTRANの文法上の規則である。Iから始まる6文字に決まったのはIntegerの頭文字Iを連想しやすいからと思われる。
FORTRANのプログラムでは、特にループ構造を表すDO構文におけるカウンター変数としてアルファベットI~Nの1文字の変数名が伝統的によく使用されており、プログラミングにおける慣習上の変数命名規則の一つとなっている。FORTRANを参考にしたといわれるBASICにおいてもプログラミングにおける慣習上の変数命名規則が同様に存在し、ループ構造であるFOR~NEXT等には、アルファベットI~Nの1文字の変数名が伝統的に使用されている。さらに、Cその他のプログラミング言語のプログラミングにおいても伝統的にこれらの変数名が整数型の変数の変数名として使用されている。このようなプログラミングにおける変数命名規則の伝統・慣習は、FORTRANの暗黙の型宣言に由来している。なお、「変数の型はすべて明示的に宣言すべきであり暗黙の型宣言は不要である」とする見解もある。いずれにしても、半世紀以上の歴史のあるFORTRANは、一般的なプログラミングにおける変数命名規則の慣習に与えた影響も大きいといえよう。
Fortran 90以降ではIMPLICIT NONE文により暗黙の型宣言を無効にできるようになった。コンパイラのエラーメッセージや警告により暗黙の型宣言に起因するバグの発見が容易になるので積極的に用いるべきである。
[編集] 構造化Fortran
FORTRAN 77までのFORTRANは、言語仕様が古いためにプログラムの構造化記述ができなかった。そこで、構造化記述を行なうために、プリプロセッサを使う方法が利用されていた。代表的なものとしては
がある。
[編集] FORTRANの記述の旧式さによる逸話
FORTRANで、コンマとピリオドを打ち間違えたらどうなるかの一例。
int i; (中略) for( i=1; i<=5; i++ ) { 何らかの処理; }
これをFORTRAN66で書くと次のように書ける。
DO 10 I = 1, 5 何らかの処理 10 CONTINUE
- 最初の行は、整数型変数Iを1から5まで1ずつ増加させつつ、行ラベル10の行までを繰り返し実行することを表す。行ラベル10のCONTINUE文はループ制御の端末文ではなく、どこにでも置ける「何もしない」機能の文である。
ここで、DO文行のコンマをピリオドに打ち間違えたとする。すると、空白を無視するFORTRAN66では、この行は、
DO10I = 1.5
という、「DO10Iという実数型変数に1.5という実数を代入する代入文」と解釈される。FORTRANでは変数宣言が無い場合、DO10Iは実数型変数を暗黙に示すからである。 この結果、このプログラムは(他のどこからも参照されない)変数DO10Iへの代入とただ1回の「何らかの処理」が実行されるだけとなり、意図した繰り返し処理は 起こらない。
C言語などでは、空白文字は字句要素の切れ目として解釈されるため、DO と 10 と Iが結合して一つの字句要素になることはない。BASICにも、空白文字が字句要素の切れ目を表さないものがある。
上記と同様のバグによってNASAの宇宙ロケットが制御不能になり、爆破されたという逸話が度々語られる。しかしこれは二つの事故を混同し、さらに誇張されたものであることが、その後の調査により解っている。当事者達によるインターネット投稿を要約すると以下のとおり。
火星探査機マリナー1号はRate SystemおよびTrack Systemと呼ばれる二種類の制御系統を持っていた。Rate Systemは搭載型であり、地上型のTrack Systemは前者に対するバックアップとして動作する。1962年7月マリナー1号を打ち上げると、Rate Systemのハードウェアが故障したため、Track Systemで制御することになった。しかしTrack Systemはプログラム段階で、手書きの数式中のバー記号が見落とされており、微妙なタイミング差の平滑化処理に問題があった。その結果、制御コンピュータは、マリナー1号が正常に上昇しているにも関わらず、異常な補正動作をマリナー1号に指示し続けることとなった。大事をとった制御官はマリナー1号を爆破し、同機は大西洋へと沈んだ。
これとは別に、1963年マーキュリー宇宙船の軌道計算ソフトウェアを開発中に、スタッフの一人が計算精度に問題があることに気づいた。コードを調査した結果、「DO 10 I=1.10」という行を発見した。これを「DO 10 I=1,10」と修正したところ、期待した精度が得られるようになった。ただしこのバグによる誤差はほんの僅かであり、実際の宇宙飛行には全く問題ない程度であった。
[編集] 規格
両者とも、次の3部からなる。
- 第1部:基底言語
- 第2部:可変長文字列
- 第3部:条件付き翻訳
[編集] 主な処理系
- GNU Fortran 95(gfortran) - GNUのFortran95処理系、GCCのバージョン4.0.0以降より標準
- GNU Fortran 77 (g77) - GNUのFortran77処理系、GCCのバージョン4.0.0以前の標準
- http://kkourakis.tripod.com/g77.htm - g77のWindows版
- f2c - ベル研究所のFortran77をC言語に変換するトランスレータ