とほほのFORTRAN入門

目次

FORTRANとは

ここでは、ノスタルジーを感じるために、懐かしの 「FORTRAN 77」 についてさわりだけ紹介してみます。

インストール

# CentOS 7
# yum -y install gcc-gfortran libgfortran

Hello world

      PROGRAM HELLO
      PRINT *, 'HELLO, WORLD!'
      END PROGRAM HELLO
$ gfortran hello.f -o hello
$ ./hello
HELLO, WORLD!

カラム

Fortran 90 では自由形式で記述できますが、FORTRAN 77 までは下記の様な固定形式でした。

0        1         2         3         4         5         6         7         8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
C THIS IS COMMENT LINE.
      PROGRAM SAMPLE                                                    COMMENT
      DO 100 I=1,5                                                      COMMENT
        PRINT *, I
 100  CONTINUE
      END PROGRAM SAMPLE

キーワード

ACCEPT
ASSIGN
AUTOMATIC
BACKSPACE
BLOCK DATA
BYTE			# 1バイト整数
CALL			# サブルーチンコール
CHARACTER		# 文字
CLOSE			# ファイルを閉じる
COMMON
COMPLEX			# 虚数
CONTINUE		# 何もしない
DATA
DECODE
DIMENSION		# N次元配列
DO			# DO文
DO WHILE		# 繰り返し
DOUBLE			# 倍精度
ELSE			# IF文
ELSE IF			# IF文
ENCODE
END			# 終わり
ENTRY
EQUIVALENCE
EXTERNAL
FORMAT			# フォーマット指定
FUNCTION		# 関数定義
GOTO			# GOTO文
IF			# IF文
IMPLICIT		# 暗黙の型定義
INCLUDE
INQUIRE
INTEGER			# 整数
INTRINSIC
LOGICAL			# 真偽値
MAP
NAMELIST
OPEN			# ファイルオープン
OPTIONS
PARAMETER
PAUSE			# 一時中断
POINTER
PRINT			# 出力
PROGRAM			# プログラムの開始
READ			# データ入力
REAL			# 実数
RECORD
RETURN			# 戻り値分岐
REWIND
SAVE
STATIC
STOP			# プログラム停止
STRUCTURE
SUBROUTINE		# サブルーチン
TYPE
UNION
VIRTUAL
VOLATILE
WRITE			# ファイル出力

文字(CHARACTER)

      CHARACTER S(2)*3
      S(1)='AAA'
      S(2)='BBB'

真偽値(LOGICAL)

      LOGICAL F1, F2
      F1=.TRUE.
      F2=.FALSE.

1バイト整数(BYTE)

      BYTE B				# 1バイト整数B
      BYTE B/127/			# 初期化

整数(INTEGER)

      INTEGER N, M			# 整数NとM
      INTEGER N(2), M(3)		# N(1), N(2), M(1), M(2), M(3)
      INTEGER N/123/, M/234/		# 初期化
      INTEGER*2 N			# 2バイト整数N
      INTEGER*4 N			# 4バイト整数N
      INTEGER*8 N			# 8バイト整数N

実数(REAL)

      REAL X, Y			# 実数XとY
      REAL X/12.3/			# 初期化(12.3)
      REAL X/1.23E2/			# 初期化(1.23×102)
      REAL*4 X, Y			# 4バイト実数
      REAL*8 X, Y			# 8バイト実数
      REAL*8 X/1.23D2/			# 初期化(1.23×102)
      REAL*16 X, Y			# 16バイト実数
      REAL*16 X/1.23Q2/		# 初期化(1.23×102)

虚数(COMPLEX)

      COMPLEX X, Y			# 虚数XとY
      COMPLEX X/(1.0,2.0)/		# 初期化
      COMPLEX*8 X			# 8バイト虚数
      COMPLEX*16 X			# 16バイト虚数
      COMPLEX*32 X			# 32バイト虚数

倍精度(DOUBLE)

      DOUBLE PRECISION X		# REAL*8と同意
      DOUBLE COMPLEX X			# COMPLEX*16と同意

N次元配列(DIMENSION)

      DIMENSION N(2)			# N(1), N(2)
      DIMENSION N(2,3)			# N(1,1), ..., N(2,3)
      DIMENSION N(-2:2)		# N(-2), ..., N(2)

演算子

+		# 加算
-		# 減算
*		# 乗算
/		# 除算
**		# べき乗
.LT.		# より小さい(Less Than)
.LE.		# 以下(Less than or Equal to)
.EQ.		# 等しい(EQual to)
.NE.		# 等しくない(Not Equal to)
.GE.		# 以上(Greater than or Equal to)
.GT.		# より大きい(Greater Than)
.OR.		# または(OR)
.AND.		# かつ(AND)
.NOT.		# 否定(NOT)

変数

暗黙的に、I~L で始まる変数は整数、その他は実数とみなされます。

制御構文

CONTINUE文

      CONTINUE				# 何もしない

GOTO文

      GOTO 100				# 行番号100にジャンプする
      PRINT *, 'NOT PRINTED THIS LINE'
100   PRINT *, 'HERE!'

DO文

      DO 100 I=1,5			# 行番号100との間を5回繰り返す
        PRINT *, I
100   CONTINUE

DO WHILE文

      N=1
      DO WHILE (N .LT. 10)		# Nが10より小さい間繰り返す
        PRINT *, N
        N=N+1
      END DO

IF文

      IF (A1 .GT. A2) THEN		# もしA1がA2より大きければ
        PRINT *, 'BIG!'
      ELSE IF (A1 .EQ. A2) THEN	# 等しければ
        PRINT *, 'EQUAL!'
      ELSE				# さもなくば
        PRINT *, 'SMALL!'
      ENDIF

IF文

      IF (N) 100, 110, 120		# Nの値によって
100   PRINT *, 'A'			# 負数なら100に、
110   PRINT *, 'B'			# 0なら110に、
120   PRINT *, 'C'			# 正数なら120にジャンプする

PAUSE文

      PAUSE				# プログラムを一時中断する

STOP文

      STOP				# プログラムを中止する

入出力

PRINT文

      PRINT *, A, B			# 標準形式
      PRINT '(I5)', N			# 5桁の整数(I:10進数, O:8進数, Z:16進数)
      PRINT '(F6.2)', X		# 小数部2桁、全体6桁の実数(F:固定小数, E:指数, D:倍精度, G:自動)
      PRINT '(A)', 'HELLO'		# 文字
      PRINT '(L)', FLAG		# 真偽値 (真ならT, 偽ならFを出力)
      PRINT '(F4.1, F5.2)', X, Y	# 複数の値を出力

FORMAT文

      PRINT 100, X, Y			# 行番号100で指定したフォーマットで出力
100   FORMAT (F4.2, ' ', F6.3)

OPEN文

      OPEN(100, FILE="sample.dat")	# ファイルをオープンし、ユニット番号100を割り当てる

READ文

      READ (*, *), N			# 標準入力から標準フォーマットで読み込む
      READ (*, '(I3)'), N		# 標準入力から3桁の整数値フォーマットで読み込む
      OPEN(100, FILE='sample.dat')	# ファイルをオープンし、ユニット番号100を割り当てる
      READ (100, *), N			# ユニット番号100のファイルから標準フォーマットで読み込む

WRITE文

      WRITE (*, *), N			# 標準出力に標準フォーマットで書き出す
      WRITE (*, '(I3)'), N		# 標準出力に3桁の整数値フォーマットで書き出す
      OPEN(100, FILE='sample.dat')	# ファイルをオープンし、ユニット番号100を割り当てる
      WRITE (100, *), N		# ユニット番号100のファイルに標準フォーマットで書き込む

CLOSE文

      CLOSE (100)			# OPEN()で開いたファイルを閉じる

関数・サブルーチン

FUNCTION文

      PROGRAM MAIN
      Z=TASHIZAN(2.3, 3.4)		# 関数を呼び出す
      PRINT *, Z
      END PROGRAM MAIN

      FUNCTION TASHIZAN(X, Y)		# 関数を定義する
        TASHIZAN=X+Y			# 関数と同じ変数名が戻り値
        RETURN
      END FUNCTION TASHIZAN

SUBROUTINE文

      SUBROUTINE TASHIZAN(X,Y,Z)	# サブルーチンを定義
        REAL :: X, Y, Z
        Z=X+Y
      END SUBROUTINE TASHIZAN

CALL文

      PROGRAM MAIN
        X=12.3
        Y=23.4
        CALL TASHIZAN(X,Y,Z)		# サブルーチンを呼び出す
        PRINT *, Z
      END PROGRAM MAIN

RETURN文

      PROGRAM MAIN
        N=123
        M=234
        CALL HIKAKU(N, M, *110, *120)	# RETURNに対応する行番号にジャンプする
        PRINT *, 'EQUAL'		# 無値であればEQUALを表示
        GOTO 130
110     PRINT *, 'SMALL'		# 1であればSMALLを表示
        GOTO 130
120     PRINT *, 'BIG'			# 2であればBIGを表示
130     CONTINUE
      END PROGRAM MAIN

      SUBROUTINE HIKAKU(N, M, *, *)
        IF (N .EQ. M) THEN
          RETURN			# 等しければ無値を返す
        ELSE IF (N .LT. M) THEN
          RETURN 1			# 小さければ1を返す
        ELSE
          RETURN 2			# 大きければ2を返す
        END IF
      END SUBROUTINE

その他

IMPLICIT文

      IMPLICIT INTEGER (A-Z)		# A~Zで始まる変数は整数とみなす
      IMPLICIT REAL (X-Z)		# X~Zで始まる変数は実数とみなす