FORTRAN 77の言語仕様

FORTRAN 77の言語仕様（フォートランななじゅうななのげんごしよう）は、FORTRAN 66とFORTRAN 77の言語仕様と、言語仕様にまつわるエピソードについて解説している。なお、Fortran 90以降の言語仕様については、Fortranの言語仕様を参照のこと。
言語仕様.
Fortranの言語仕様は、年代によってかなり変化して来ている。他のプログラミング言語で実装された構造化プログラミングの機能などがどんどん取り入れられて来ているからである。
FORTRAN 66.
FORTRAN 66の言語仕様はおおよそ下記のとおり。
プログラムの書式.
プログラムは以下の形式で記述する。もともとパンチカードに書くことを前提としていたので、1行は80文字で構成されていた。行の左端からの文字位置を桁（けた）またはカラムと呼んだ。
もともとのFORTRANは、字句解析の仕組みがCやJavaと大きく異なり、桁位置（行の左端からの文字位置）に依存していた。これを"固定プログラム形式"という。これは、当時、データの入力にパンチカードを 使用していたためである。1桁目から5桁目が文番号で、6桁目が継続行の指定、7桁目から72桁目に文の本体を記述する。73桁目から80桁目は任意に指定可能な、行を識別するための文字列を記述する領域である。また、文字列定数中以外の空白文字は一切無視されていた。二つ以上の字句を空白無しで続けて書 いたり、逆に一つの字句の途中に空白文字を入れても構わない。
物理的に穴を開けるパンチカードのほかに、鉛筆で塗りつぶすマークシート方式も存在した。消しゴムで消せば楽に修正できるわけである。いずれも、カード1枚がプログラム1行に相当する。これらは「FORTRANカード」と呼ばれた。
数など.
以下の数を扱える。
変数など.
以下の変数宣言を扱える。
関数.
以下の関数を扱える。
FORTRAN 77.
FORTRAN 77は、FORTRAN 66に、よりプログラムを書きやすくするための文や、動作の明確化をはかっている。FORTRAN 66でのプログラムはほぼそのまま動くようになっている。以下はFORTRAN 77で追加/変更になった点の概要である。
変数など.
変数などについて以下の変更が加えられた。
関数.
以下の関数が追加された。
FORTRANの言語仕様にまつわるエピソード.
暗黙の型宣言による伝統的・慣習上の変数命名規則.
FORTRANのプログラムにおいては、とくに型宣言をしない場合、アルファベットI,J,K,L,M,Nのいずれかで始まる変数名で表される変数は整数型（integer）になり、その他のアルファベット（A～H, O～Z）で始まるものは実数型（real）になる。これが「暗黙の型宣言」といわれるFORTRANの文法上の規則である。なお、この命名規則についてBakusは『Iから始まる6文字に決まったのは、みんな添え字にI、J、Kをつかっていたので、(L、M、Nを)気前よく増やした。』と言っている。
FORTRANのプログラムでは、特にループ構造を表すDO構文におけるカウンター変数としてアルファベットI～Nの1文字の変数名が伝統的によく使用されており、プログラミングにおける慣習上の変数命名規則の一つとなっている。i, j...の1文字変数をインデックス参照などに使われるループカウンタに使うことは、他の多くのプログラミング言語に伝搬したが、プログラミング言語における慣習としてはFORTRANに由来する（数学の総和などでもiを使う慣習があるので、プログラミング言語以外について含めたら、必ずしもFORTRANが元祖とは言い切れない）。
いくつかの観点から、変数には明示的な宣言が必要とされることもある。Fortran 90以降ではIMPLICIT NONE文により暗黙の型宣言を無効にできるようになった。コンパイラのエラーメッセージや警告により暗黙の型宣言に起因するバグの発見が容易になるので積極的に用いるべきである。
言語仕様と宇宙開発にまつわるエピソード.
FORTRANの「空白は無視する」という言語仕様が招く、コンマとピリオドの打ち間違いがコンパイルエラーにならず、間違ったプログラムになる、という例を説明する。
Cで、次のように書くプログラムの一部があったとする。
 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が結合して一つの字句要素になることはない。
「これが原因でNASAの宇宙ロケットが制御不能になり爆破された」という話が度々語られる。しかしこの話は、1960年代前半のほぼ同時期にあった、二つの異なった事件の混同による、ある種の「都市伝説」である。
要約すると、
DO文によるバグは、1963年、マーキュリー宇宙船の軌道計算ソフトウェアを開発中に、スタッフの一人が計算精度に問題があることに気づいた。コードを調査した結果、「DO 10 I=1.10」という行を発見した。それが原因で、ループにより近似の精度を高めるはずのコードが、ループしないため精度を高めることなく通り過ぎてしまっていた。これを「DO 10 I=1,10」と修正したところ、期待した精度が得られるようになった。
宇宙機の喪失につながった事故は、1962年、金星探査機マリナー1号を打ち上げるアトラスロケットには、Rate SystemおよびTrack Systemと呼ばれる二種類の制御系統が搭載されていた。Rate Systemは搭載型であり、地上型のTrack Systemは前者に対するバックアップとして動作する。1962年7月、マリナー1号の打ち上げ直後に、ロケットのguidanceアンテナは必要な性能を発揮しなくなり、搭載型システムのみに頼ってロケットは制御されることになった。しかし搭載型システムには次のような仕様バグがあった。「このようにプログラムすべき」として指示されていた手書きの数式中の、平均化を示す線（しばしば「ハイフン」と言及されるが、正確にはオーバーライン）が欠落しており、そのため平均化した値を使うべきところでそのままの値が使われ、微妙なタイミング差の平滑化処理に問題があった（プログラム自体は「指示された仕様の通り」正しく書かれていた。指示された仕様が間違っていたのである）。結果として、制御コンピュータは、ロケットが正常に上昇しているにも関わらず、異常な補正動作をロケットに指示し続け、正常なコースから外れていった。結局、ロケットには破壊指令が送られ自爆し、マリナー1号は大西洋へと沈んだ。