- Fortran 77・90/95・Modern Fortranの違い|昔と今のコード比較
- 最初に押さえておきたいFortranの世代
- 最大の違い|固定形式と自由形式
- ソースファイルの拡張子にも違いがある
- Hello Worldを比較する
- コメントの書き方を比較する
- DO文の違い
- IF文を比較する
- 変数宣言を比較する
- implicit noneの重要性
- 配列の扱いを比較する
- 動的配列の違い
- 関数の書き方を比較する
- サブルーチンを比較する
- COMMONとMODULEの違い
- GOTOは現在でも使える?
- 比較演算子の昔と今
- 文字列の扱い
- SELECT CASEを使える
- 同じ処理を3世代で比較|1から10までの合計
- 同じ処理を比較|配列の平均値
- 昔のFortranコードは現在でも動く?
- 古いコードで見かける機能
- gfortranで古いコードを試す
- Fortran 90/95を学んだ人はどの程度そのまま使える?
- 新しいコードではどの書き方を使えばよい?
- 昔の書き方を学ぶ意味はある?
- Fortranの変化をまとめる
- まとめ
Fortran 77・90/95・Modern Fortranの違い|昔と今のコード比較
Fortranは非常に長い歴史を持つプログラミング言語です。
そのため、「Fortran」と一言でいっても、
FORTRAN 77、Fortran 90、Fortran 95、
さらにFortran 2003、2008、2018、2023など、
複数の世代があります。
昔Fortranを学んだ人が現在のコードを見ると、
「同じFortranなのにかなり書き方が違う」と感じることがあります。
一方で、基本的な考え方や多くの構文は現在まで受け継がれています。
この記事では、
Fortran 77、
Fortran 90/95、
Modern Fortranの違いを、
同じ処理を実際のコードで並べながら比較します。
コード内には「!」による注釈も入れ、
どこが昔の書き方で、どこが現在の書き方なのかを
初学者にも分かりやすく説明します。
最初に押さえておきたいFortranの世代
| 規格 | 主な特徴 |
|---|---|
| FORTRAN 77 | 固定形式、行番号、古いDO文などが代表的 |
| Fortran 90 | 自由形式、配列演算、MODULEなどを導入 |
| Fortran 95 | Fortran 90を整理・拡張 |
| Fortran 2003 | オブジェクト指向、Cとの相互運用などを強化 |
| Fortran 2008 | 並列処理関連などを拡張 |
| Fortran 2018 | 並列・相互運用などをさらに整理・拡張 |
| Fortran 2023 | 現在の新しい規格世代 |
この記事では、
Fortran 2003以降の世代をまとめて
Modern Fortranと呼んで説明します。
ただし、「Modern Fortran」という名称は特定の1つの規格名ではなく、
一般にFortran 90以降、特に2003以降の現代的な書き方を指す言葉として使われます。
最大の違い|固定形式と自由形式
FORTRAN 77では、
固定形式(fixed form)という書き方が一般的でした。
固定形式では、
コードを書く桁位置に意味があります。
これはパンチカード時代の設計を引き継いだものです。
PROGRAM HELLO
PRINT *, 'HELLO'
END
左側に空白が並んでいるのは単なる見た目ではありません。
FORTRAN 77では、列位置が重要でした。
一方、Fortran 90以降では
自由形式(free form)が利用できるようになりました。
program hello
implicit none
print *, "Hello"
end program hello
現在のFortranでは、
一般的なプログラミング言語と同じように
インデントを自由に付けて読みやすく書けます。
ソースファイルの拡張子にも違いがある
一般的に、古い固定形式のFortranコードでは
.fや.forが使われることがあります。
自由形式のFortranでは
.f90が広く使われています。
| 例 | 意味 |
|---|---|
| sample.f | 固定形式として扱われることが多い |
| sample.for | 古いFortranコードで見かけることがある |
| sample.f90 | 自由形式のFortranで広く使われる |
拡張子の数字は、
必ずしも「その規格しか書けない」という意味ではありません。
現在でもModern Fortranの自由形式コードに
.f90を使用するのが一般的です。
Hello Worldを比較する
FORTRAN 77風
PROGRAM HELLO
C Cで始まる行は古い形式のコメントです。
PRINT *, 'HELLO, FORTRAN'
END
Fortran 90/95風
program hello
implicit none
! Fortran 90以降では ! でコメントを書けます。
print *, "Hello, Fortran"
end program hello
Modern Fortran
program hello
implicit none
print *, "Hello, Fortran!"
end program hello
Hello World程度では、
Fortran 90/95とModern Fortranの見た目はほとんど変わりません。
大きく違うのは、
FORTRAN 77の固定形式から
Fortran 90以降の自由形式へ移った点です。
コメントの書き方を比較する
FORTRAN 77
C THIS IS A COMMENT
X = 10.0
固定形式では、
1列目にCや*などを書くコメント形式が使われていました。
Fortran 90以降
! この行はコメントです。
x = 10.0 ! 行の途中にもコメントを書けます。
現在は!を使う書き方が分かりやすく、
一般的です。
DO文の違い
繰り返し処理は、
昔と今の違いが特に分かりやすい部分です。
FORTRAN 77
INTEGER I
C Iを1から5まで変化させます。
DO 100 I = 1, 5
PRINT *, I
C 100番の文までがDOループです。
100 CONTINUE
END
100は行番号(文番号)です。
DO文では「100番の文まで繰り返す」という書き方が使われました。
Fortran 90/95
program do_example
implicit none
integer :: i
do i = 1, 5
print *, i
end do
end program do_example
Modern Fortran
program do_example
implicit none
integer :: i
do i = 1, 5
print *, i
end do
end program do_example
現在ではend doで
繰り返し範囲を明確に書けます。
Fortran 90/95を学んだ人であれば、
この書き方は現在でもほぼそのまま通用します。
IF文を比較する
古い算術IF
非常に古いFortranでは、
値が負・0・正のどれかによって
3つの行番号へ分岐する算術IFが使われることがありました。
IF (X) 10, 20, 30
10 PRINT *, 'NEGATIVE'
GO TO 40
20 PRINT *, 'ZERO'
GO TO 40
30 PRINT *, 'POSITIVE'
40 CONTINUE
現在のコードとしてはかなり読みづらく、
新しく書く場合に使う必要はありません。
Fortran 90/95以降
if (x < 0.0) then
print *, "negative"
else if (x == 0.0) then
print *, "zero"
else
print *, "positive"
end if
現在では、
こちらの構造化されたIF文を使う方が
はるかに分かりやすくなります。
変数宣言を比較する
FORTRAN 77風
INTEGER I
REAL X
REAL Y
Fortran 90/95以降
integer :: i
real :: x, y
::を使った宣言は、
Fortran 90以降の現代的な書き方です。
implicit noneの重要性
古いFortranでは、
変数名の最初の文字によって型を自動的に決める
暗黙の型付けが使われることがありました。
例えば、I~Nで始まる変数名は整数、
それ以外は実数として扱うという規則です。
X = 10.0
I = 5
宣言を書かなくても動く場合があるため、
入力ミスが別の変数として処理される危険があります。
現在は、次のようにimplicit noneを書くのが基本です。
program example
implicit none
real :: x
integer :: i
end program example
これにより、
宣言していない変数を誤って使った場合に
コンパイラが検出しやすくなります。
配列の扱いを比較する
Fortran 90で大きく進化した部分の一つが
配列処理です。
FORTRAN 77風
REAL A(3)
REAL B(3)
REAL C(3)
INTEGER I
A(1) = 1.0
A(2) = 2.0
A(3) = 3.0
B(1) = 4.0
B(2) = 5.0
B(3) = 6.0
C 各要素をDO文で足します。
DO 100 I = 1, 3
C(I) = A(I) + B(I)
100 CONTINUE
Fortran 90/95
program array_example
implicit none
real :: a(3)
real :: b(3)
real :: c(3)
a = (/ 1.0, 2.0, 3.0 /)
b = (/ 4.0, 5.0, 6.0 /)
! 配列全体を一度に加算できます。
c = a + b
end program array_example
Modern Fortran
program array_example
implicit none
real :: a(3)
real :: b(3)
real :: c(3)
! 現在は [ ] を使った配列コンストラクタも利用できます。
a = [1.0, 2.0, 3.0]
b = [4.0, 5.0, 6.0]
c = a + b
print *, c
end program array_example
Fortran 90以降では、
配列全体を1つの式として計算できるようになりました。
これは科学技術計算における大きな利点です。
動的配列の違い
FORTRAN 77では、
配列サイズをあらかじめ固定しておく使い方が一般的でした。
REAL DATA(1000)
Fortran 90以降では、
allocatableを使って
実行時に必要なサイズを確保できます。
program allocatable_example
implicit none
integer :: n
real, allocatable :: data(:)
print *, "要素数を入力してください。"
read *, n
! 実行時にn個の配列を確保します。
allocate(data(n))
! ここでdataを使用します。
! 使用後に領域を解放します。
deallocate(data)
end program allocatable_example
必要なデータ数が実行時まで分からない場合に便利です。
関数の書き方を比較する
FORTRAN 77風
REAL FUNCTION SQUARE(X)
REAL X
C 関数名そのものへ値を代入して返します。
SQUARE = X * X
RETURN
END
Fortran 90/95以降
function square(x) result(answer)
implicit none
real, intent(in) :: x
real :: answer
answer = x * x
end function square
Modern Fortranでは、
resultやintentを使うことで、
入力と出力の意味を明確に書けます。
サブルーチンを比較する
FORTRAN 77風
SUBROUTINE CALC(A, B, C)
REAL A, B, C
C = A + B
RETURN
END
Modern Fortran
subroutine calc(a, b, c)
implicit none
! aとbは入力専用です。
real, intent(in) :: a
real, intent(in) :: b
! cは出力用です。
real, intent(out) :: c
c = a + b
end subroutine calc
intent(in)やintent(out)によって、
引数の役割がコードを見ただけで分かります。
COMMONとMODULEの違い
古いFortranでは、
複数のプログラム単位で変数を共有するために
COMMONが使われることがありました。
FORTRAN 77風
REAL A, B
COMMON /DATA/ A, B
COMMONは古いコードで頻繁に見かけますが、
変数の管理が分かりにくくなることがあります。
Fortran 90以降では、
MODULEを使って
変数や関数、サブルーチンなどを整理できます。
Fortran 90以降
module constants
implicit none
real, parameter :: pi = 3.14159265
end module constants
利用する側ではuseを書きます。
program circle
use constants
implicit none
real :: radius
real :: area
radius = 5.0
area = pi * radius ** 2
print *, area
end program circle
MODULEはModern Fortranで非常に重要な仕組みです。
GOTOは現在でも使える?
Fortranにはgotoがあります。
昔のFortranコードでは、
行番号と組み合わせて処理を移動するコードをよく見かけます。
IF (X .GT. 0.0) GO TO 100
PRINT *, 'ZERO OR NEGATIVE'
GO TO 200
100 PRINT *, 'POSITIVE'
200 CONTINUE
現在でも一部のgoto構文は利用できますが、
新しいコードでは、
IF、DO、SELECT CASEなどを使って
構造化して書く方が読みやすくなります。
比較演算子の昔と今
古いコードでは、
次のような文字形式の比較演算子をよく見かけます。
| 古い表記 | 現在よく使う表記 | 意味 |
|---|---|---|
| .EQ. | == | 等しい |
| .NE. | /= | 等しくない |
| .GT. | > | より大きい |
| .LT. | < | より小さい |
| .GE. | >= | 以上 |
| .LE. | <= | 以下 |
古い書き方
IF (X .GT. 10.0) THEN
PRINT *, 'LARGE'
END IF
現在の書き方
if (x > 10.0) then
print *, "large"
end if
古い文字形式の演算子も現在のコンパイラで扱えることがありますが、
新しいコードでは記号形式の方が一般的です。
文字列の扱い
FORTRAN 77風
CHARACTER*20 NAME
NAME = 'FORTRAN'
Modern Fortran
character(len=20) :: name
name = "Fortran"
character(len=20)のように書く方が
意味が明確です。
SELECT CASEを使える
Fortran 90以降では、
複数条件の分岐にselect caseを利用できます。
program select_example
implicit none
integer :: number
number = 2
select case (number)
case (1)
print *, "one"
case (2)
print *, "two"
case default
print *, "other"
end select
end program select_example
昔の大量のGOTOを使った分岐より、
処理の構造が分かりやすくなります。
同じ処理を3世代で比較|1から10までの合計
FORTRAN 77
PROGRAM SUM10
INTEGER I
INTEGER TOTAL
TOTAL = 0
C 1から10まで繰り返します。
DO 100 I = 1, 10
TOTAL = TOTAL + I
100 CONTINUE
PRINT *, TOTAL
END
Fortran 90/95
program sum10
implicit none
integer :: i
integer :: total
total = 0
do i = 1, 10
total = total + i
end do
print *, total
end program sum10
Modern Fortran
program sum10
implicit none
integer :: numbers(10)
integer :: i
integer :: total
! 配列へ1~10を代入します。
do i = 1, 10
numbers(i) = i
end do
! sumを使って配列全体を合計できます。
total = sum(numbers)
print *, total
end program sum10
Modern Fortranでは、
DO文を使う方法ももちろん有効ですが、
配列処理や組み込み関数を使って
より簡潔に書ける場面があります。
同じ処理を比較|配列の平均値
FORTRAN 77風
PROGRAM AVERAGE
REAL DATA(5)
REAL TOTAL
REAL AVG
INTEGER I
DATA(1) = 10.0
DATA(2) = 20.0
DATA(3) = 30.0
DATA(4) = 40.0
DATA(5) = 50.0
TOTAL = 0.0
DO 100 I = 1, 5
TOTAL = TOTAL + DATA(I)
100 CONTINUE
AVG = TOTAL / 5.0
PRINT *, AVG
END
Modern Fortran
program average
implicit none
real :: data(5)
real :: average_value
data = [10.0, 20.0, 30.0, 40.0, 50.0]
! sumで合計し、sizeで要素数を取得します。
average_value = sum(data) / real(size(data))
print *, average_value
end program average
この比較を見ると、
配列演算や組み込み関数によって
現代のFortranコードがかなり簡潔になっていることが分かります。
昔のFortranコードは現在でも動く?
多くの場合、
現在のFortranコンパイラは古いコードとの互換性をかなり重視しています。
例えばGNU Fortran(gfortran)は、
FORTRAN 77やFortran 90/95のコードを
現在でも多数コンパイルできます。
Fortran 90/95で書かれた自由形式コードであれば、
現在のgfortranでもかなりそのまま使える場合があります。
一方、非常に古いコードでは、
現在の規格から削除された機能や、
非推奨になった機能が含まれていることがあります。
古いコードで見かける機能
- 固定形式
- 文番号付きDO
- 算術IF
- assigned GO TO
- COMMON
- 古いDATA文
- 古いFORMAT文
- 暗黙の型付け
このようなコードは、
そのまま動く場合もあれば、
コンパイラオプションやコード修正が必要になる場合もあります。
gfortranで古いコードを試す
例えば古い固定形式コードが
old.fという名前で保存されている場合、
まずは通常どおりコンパイルしてみます。
gfortran old.f -o old
古い拡張機能が使われている場合は、
gfortranのレガシーモードが役立つことがあります。
gfortran -std=legacy old.f -o old
ただし、
レガシーモードで動くからといって
新しいプログラムでも古い書き方を使う必要はありません。
既存コードを動かす場合は互換機能を利用し、
新しく書くコードではModern Fortranの読みやすい構文を使う、
という考え方が分かりやすいでしょう。
Fortran 90/95を学んだ人はどの程度そのまま使える?
Fortran 90/95を学んだ経験がある場合、
現在のFortranでも基本的な知識の多くはそのまま利用できます。
例えば次のようなものは現在でも重要です。
- program ~ end program
- implicit none
- integer、real、character
- IF ~ THEN ~ END IF
- DO ~ END DO
- 配列
- function
- subroutine
- module
- allocate / deallocate
つまり、
Fortran 90/95は「完全に古い別言語」ではありません。
現在のModern Fortranへ直接つながる重要な世代です。
新しいコードではどの書き方を使えばよい?
これからFortranを学ぶ場合は、
基本的にModern Fortranの書き方を使うのがおすすめです。
例えば次のような方針です。
- 自由形式で書く
- .f90を使用する
- implicit noneを書く
- DO ~ END DOを使う
- 構造化IFを使う
- 配列演算を利用する
- COMMONよりMODULEを使う
- 引数にはintentを付ける
- 必要に応じてallocatableを使う
昔の書き方を学ぶ意味はある?
新しいプログラムを書くためだけなら、
FORTRAN 77の古い構文を覚える必要はあまりありません。
しかし、研究機関、大学、企業などでは、
何十年も改良されてきたFortranコードが残っていることがあります。
そのため、
古いFortranコードを読む必要がある人にとっては、
固定形式、行番号、COMMON、文番号付きDOなどを
知っておくと役立ちます。
特に、
「昔のコードを現在の環境へ移植する」
「古い科学計算プログラムを理解する」
という場面では重要です。
Fortranの変化をまとめる
| 項目 | FORTRAN 77 | Fortran 90/95 | Modern Fortran |
|---|---|---|---|
| ソース形式 | 固定形式が中心 | 自由形式を導入 | 自由形式が一般的 |
| DO | 文番号を利用することが多い | END DO | END DO |
| 配列演算 | DOループ中心 | 配列全体の演算が可能 | さらに活用 |
| 動的配列 | 限定的 | ALLOCATABLE | 広く利用 |
| 共有データ | COMMON | MODULE | MODULE |
| 引数の役割 | 明示しにくい | INTENT | INTENT |
| コメント | Cなど | ! | ! |
| コードの読みやすさ | 古い形式では低くなりやすい | 大幅に改善 | さらに構造化可能 |
まとめ
FORTRAN 77と現在のFortranを比較すると、
見た目やコードの構造は大きく変わっています。
特に、
固定形式から自由形式への移行、
文番号付きDOからEND DOへの変更、
配列演算、MODULE、ALLOCATABLEなどの導入によって、
コードはかなり読みやすくなりました。
一方、Fortran 90/95はModern Fortranとの共通点が多く、
当時学んだ知識の多くは現在でも利用できます。
また、現在のgfortranは古いFortranコードも広く扱えるため、
過去の科学技術計算プログラムを現在のパソコンで動かせる場合があります。
これから新しくFortranを書く場合はModern Fortranの書き方を使い、
古いコードを読む必要があるときに
FORTRAN 77特有の構文を理解する、
という学び方が実用的でしょう。
