Fortran
Fortran
■ 参考文献
竹内則雄,平野寛和:Fortran77とFortran90,森北出版 2600円
1.はじめに
1.1 歴史

IBMのBackusらが,1950年中ごろに開発

"Formula translator","Formula translation"の略

その後,進歩して

FortranU

FortranW

が開発された.最初は比較的”軽い”言語で,融通が利いた.

1966年に米国規格協会がまとめたForan66は広く使用された.

Fortran77:Fortran66に追加機能を加えた.現在もっとも多く使用されている.

Fortran90:C言語を意識した大幅な改訂がなされた.

ページの始めへ戻る

1.2 使用可能な文字

A〜Z

0〜9



+ー*/

(),.’:

空白

¥または$

1.3 コーディング

1カラム Cか*を記入すると注釈行とみなされる

1〜5カラム 文番号(通常の設定では,空白は無視されることに注意)

6カラム ゼロ以外を記入すると継続行となる.開始行を含めて20行まで許される.

7〜72カラム 文(statement)を書く

73〜80 常に注釈とみなされる.何も記入しなくてもよい.

ページの始めへ戻る

1.4 主プログラムと副プログラム

主プログラム(main program) 普通最初に書く

副プログラム(subprogram) 主プログラムから呼び出して使う.

Function文

Subroutine文

Block Data文

1.5 実行文と非実行文

実行文(executable statement)実行時に使う

代入文

制御文

入出力文

非実行文(non-executable statement)コンパイル時に使う

宣言文

Data文

Format文

ページの始めへ戻る

2.定数と変数
2.1 算術定数

整数 0,123,4567など

普通 −231〜(231−1)の範囲

符号1ビット

数値31ビット


実数 10.9,2.345など

1.0E3→1000.0

1.23E2→123.0

符号 1ビット

指数部 7ビット

仮数部 24ビット


複素数

(1.3,2.4),(4.7E−4,2.0)など

倍精度

実数の場合

3.141592654D0

64ビット使用(複素数では128ビット)

符号 1ビット

指数部 7ビット

仮数部 56ビット

ページの始めへ戻る

2.2 論理定数

.TRUE.と.FALSE.
2.3 文字定数

’(アポストロフィ)で前後を囲まれた部分

多くの処理系で,非Fortran文字が使用可能

’AML1234’など

アポストロフィを含む場合には次のようにする.

’12’’34’

2.4 変数名

英字からはじめる

6文字以内

A,ABN,CCCなど

暗黙の型宣言

I〜N 整数

それ以外 実数

ページの始めへ戻る

2.5 型宣言文

INTEGER 整数

REAL 実数

DOUBLE PRECISION 倍精度実数

CHARACTER*8 文字型

LOGICAL 論理型


最近では,殆どのばあい次のような書き方が許される.

INTEGER*2 2バイト整数

REAL*4 4バイト実数

REAL*8 8バイト実数

例 INTEGER ABC,N,M
2.6 IMPLICIT文

IMPLICIT REAL*8(A−H,O−Z),INTEGER*2(I)

優先度は次のとおりである.

#1 型宣言文

#2 IMPLICIT文

#3 暗黙の型宣言
2.7 配列

1次元配列 A(2)

2次元配列 B(2,3)

7次元まで許される

(注意)A(2)は,原則としてA(1:2)と同じである.

しかし,処理系によっては,A(0:2)と同じ場合がある.

ページの始めへ戻る

3.式
3.1 算術代入文

I=256

J=256.1(切り捨てられる.なるべく使わない)

K=’Test’(許されない)

A=1.23

C=1.23D0(使用可能だが感心しない)

D=’Test’(許されない)
3.2 文字代入文と論理代入文

CHARACTER*7 K

K=’1234567’

K=’12’

K=’12345678’(7までしか記憶されない)


LOGICAL L

L=.FALSE.

ページの始めへ戻る

3.3 算術式

A**B べき乗

A/B 割り算

A*B 掛け算

A−B 引き算

A+B 足し算

(優先度の高い順)


A/B**C*D これは

A/(B**C)*D

(A/(B**C))*D

と同じ.

紛らわしい場合には,()をつけるのが懸命.


右辺の計算結果は次のようになる.左辺に代入されるとき,左辺の型に変換される.

整数と整数→整数

整数と実数→実数

整数と複素数→複素数

実数と実数→実数

実数と複素数→複素数


(注意)1/2 → 0

1./2 → 0.5

1/2.0 → 0.5

1./2. → 0.5

ページの始めへ戻る

3.4 関係式と論理式

関係式

.EQ.

.NE.

.LT.

.LE.

.GT.

.GE.


比較の対象は文字であってもよい(辞書と同じ順位)

算術式の方が,関係式より優先順位が高い

例: (1+2).EQ.3 → .TRUE.

   (1+2).EQ.4 → .FALSE.


論理式

.NOT. 反転

.AND. T.AND.Tのみ真

.OR.  どちらかTなら真

.EQV. 等しければ真

.NEQV. 異なっていれば真


関係式の方が,論理式より優先順位が高い

例: (A.GT.−C).AND.(A.LT.C)
3.5 文字式

// 文字演算子

’ABN’//’ABC’→’ABNABC’

X=’ABC’//’DEF’

ページの始めへ戻る

4.入出力
4.1 書式なし入出力

READ(*,*) A

READ(*,*) A,B,C

多くの処理系で,READ(5,*)としても同じ.


READ(*,*)(A(I),I=1,N)

READ(*,*)(A(I),I=2,7,2) 2,4,6を読み込む


READ(*,*)I,A,CHAR

1 0.0 ’A’

1,0.0,’A’

1,,’A’

1/ (Iにのみ値が代入される)


WRITE(*,*) A

WRITE(*,*) A,B,C

多くの処理系では,WRITE(6,*)としても同じ


WRITE(*,*) (I,I=1,2)

WRITE(*,*) (A(I),I=1,4)

WRITE(*,*) ’TEST’

ページの始めへ戻る

4.2 FORMAT文

文番号 FORMAT(書式の指定)


行送り(Format文の先頭の文字で指定)

’ ’,1H  改行

’0’,1H0 2行改行

’1’,1H1 改ページ

’+’,1H+ 重ね印字


アポストロフィ編集記述子 ’*************’

H形編集記述子 nH*********


A形編集記述子 An n文字の入出力

X形編集記述子 nX ブランクn個

I形編集記述子 In 整数形データ.n桁確保

F形編集記述子 Fn.d 実数形データ.n桁確保.dは小数点以下の桁数

E形編集記述子 En.d 実数形データ.n桁確保.dは小数点以下の桁数

D形編集記述子 Dn.d 実数形データ.n桁確保.dは小数点以下の桁数

ページの始めへ戻る

4.3 書式付入出力

例1

CHARACTER M*3

READ(*,500)I,M,A

500 FORMAT(I5,A3,F10.0)

WRITE(*,*) I,M,A

STOP 

END


入力は,**123ABC*****2.345

出力は,123 ABC 2.345


例2

INTEGER I(3)

READ(*,500) (I(J),J=1,3)

500 FORMAT(3I5)

WRITE(*,*) (I(J),J=1,3)

STOP

END


入力は,****1****2****3

出力は,1 2 3


例3

CHARACTER M*3

I=123

A=123.456

M=’ABC’

WRITE(*,600) I,M,A

600 FORMAT(’ ’,I5,A3,F10.3)

STOP

END


出力は,**123ABC***123.456

書式を少しずつ変えると面白い.

600 FORMAT(’ ’,I5,2X,A3,F10.3)

600 FORMAT(’ ’,I5,2X,A3,E10.3)

600 FORMAT(’ ’,I5,’  ’,A3,F10.3)

600 FORMAT(’ ’,I5,2(’ ’),A3,F10.3)

600 FORMAT(’ ’,I5,/,A3,F10.3)

600 FORMAT(’ ’,I5,//,A3,F10.3)

(注意)/を斜線記述子という

ページの始めへ戻る

5.制御文
5.1 終了と休止

STOP 実行中止

STOP 単に終了

STOP ’A’ 終了しAが出力される

STOP 100 終了して100が出力される

END プログラム単位の終了
5.2 繰り返し

例1

IS=0

DO 10 I=1,5

IS=I+1

 10 CONTINUE

WRITE(*,*) IS

STOP

END


例2

IS=0

DO 10 I=1,10,2

IS=I+1

 10 CONTINUE

WRITE(*,*) IS

STOP

END


例3

DO 10 I=1,2

DO 20 J=1,3

WRITE(*,*) I,J

 20 CONTINUE

 10 CONTINUE

STOP

END

ページの始めへ戻る

5.3 条件判断

IF(論理式) 実行文


IS=0

DO 10 I=1,10

IS=I+1

IF(I.GE.9)WRITE(*,*)I,IS

 10 CONTINUE

STOP

END


IF(論理式) THEN

実行文

−−−

END IF


IS=0

DO 10 I=1,10

IS=I+1

IF(I.GE.9)THEN

WRITE(*,*)I

WRITE(*,*)IS

END IF

 10 CONTINUE

STOP

END



IF(論理式) THEN

実行文

−−−

ELSE

    実行文

    −−−

END IF


IS=0

DO 10 I=1,10

IS=I+1

IF(I.GE.9)THEN

WRITE(*,*)I

ELSE

WRITE(*,*)IS

END IF

 10 CONTINUE

STOP

END


IF(算術式) 文番号1,文番号2,文番号3

負の時 ,0  ,正の時

GO TO 文番号


I=0

100 CONTINUE

I=I+1

WRITE(*,*) I

IF(I.LE.10) GO TO 100

STOP

END

ページの始めへ戻る

6.宣言文とDATA文

配列宣言 DIMENSION A(10),B(20)

REAL A(10),B(10)

REAL*8 A(10),B(10)


EQUIVALENCE文

EQUIVALENCE(A(2),K)


PARAMETER文

PARAMETER(PAI=3.14,N=20)

プログラム中で再定義できない(N=30は不可)


DATA文

DATA PAI/3.14159/

DATA A,B/1.2,2.3/

ページの始めへ戻る

7.関数と副プログラム
7.1 組み込み関数

処理系の用意した関数

総称名 引数の型に応じて,返す値の型が決められる

全ての関数が,総称名を持つわけではない

個別名 引数の型によって,関数名がことなる


IABS(I) 個別名.整数用.

ABS(A) 個別名.実数用. ならびに 総称名

DABS(D) 個別名.倍精度実数用.
7.2 文関数(statement function)

SMF1(X,Y)=X+Y

A=1

B=2

C=SMF1(A,B)

WRITE(*,*) C

STOP

END


(注意)暗黙の型宣言に従う.型宣言は次のようにするのが,わかり易い.

REAL*8 SMF1

SMF1(X,Y)=X+Y

次のコードは,多くの処理系で許されないので注意.

REAL*8 SMF1(X,Y)=X+Y

ページの始めへ戻る

7.3 関数副プログラム(function sub-program)

文関数であらわせないような複雑な式,判断を要するような場合に使う.


A=1

B=2

C=FSP1(A,B)

WRITE(*,*) C

STOP

END


REAL FUNCTION FSP1(A,B)

FSP1=A

FSP1=FSP1+B

RETURN

END


(注意)暗黙の型宣言に従う.型宣言は上記のようにするのが,わかり易い.主プログラムにおける型と矛盾しないように注意すること.

引数の再定義は許されることが多い.その場合,subroutine programと似た使い方が可能である.

ページの始めへ戻る

7.4 副プログラム(subroutine program)

副関数プログラムでは,結果として一つの値しか返せない.

これを克服するには,副プログラムを使う.


A=1

B=2

CALL SUB1(A,B,C,D)

WRITE(*,*)C,D

STOP

END


SUBROUTINE SUB1(A,B,C,D)

C=A+B

D=A-B

RETURN

END

ページの始めへ戻る

7.5 配列の扱い

REAL A(3)

CALL SUB2(A(1),A(2),A(3))

WRITE(*,*)A(1),A(2),A(3)

STOP

END


SUBROUTINE SUB2(A,B,C)

A=1.0

B=2.0

C=3.0

RETURN

END



REAL A(3)

CALL SUB2(A)

WRITE(*,*)A

STOP

END


SUBROUTINE SUB2(A)

REAL A(3)

A(1)=1.0

A(2)=2.0

A(3)=3.0

RETURN

END

ページの始めへ戻る

8.外部ファイルの利用
8.1 ファイルのオープンとクローズ

OPEN(UNIT,FILE,ACCESS,FORM

STATUS,RECL,ERR,IOSTAT,BLANK)


UNIT=数字(装置番号)

READ(数字,*)

WRITE(数字,*)

FILE=ファイル名前

FILE=’EX1.DAT’

ACCESS=’SEQUENTIAL’または’DIRECT’

省略するとSEQUENTIAL

FORM=’FORMATTED’または’UNFORMATTED’

省略すると

SEQUENTIALではFORMATTED

DIRECTではUNFORMATTED

UNFORMATTEDでは内部記録がそのまま記録される

速度が速いが,わかりにくいので注意

STATUS=’NEW’ ’OLD’ ’UNKNOWN’ ’SCRATCH’

’NEW’新しいファイルをつくる

’OLD’既存のファイルを探す

’UNKNOWN’まず既存のファイルを探す.なければファイルをつくる

’SCRATCH’ワークファイルで実行終了後消去される

RECL=数字(DIRCTファイルのレコード長)

処理系によって単位が違う

バイト単位が多いか?

ERR=数字(エラーが生じた場合のとぶ文番号)

IOSTAT=整数型の変数名

エラーなしなら,変数に0をいれる

エラーがあると,正の数

ファイルの最後に達したら,負の数

BLANK=’NULL’または’ZERO’

’NULL’なら空白無視(省略時はこちら)

’ZERO’なら空白を0とみなす


CLOSE(UNIT,STATUS,ERR,IOSTAT)


STATUS=’KEEP’または’DELETE’

KEEPならファイル保存(省略時はこちら)

DELETEならファイル消去

ページの始めへ戻る

8.2 入出力文

READ(UNIT,FMT,REC,END,ERR,IOSTAT)

WRITE(UNIT,FMT,REC,END,ERR,IOSTAT)


UNIT=数字(装置番号),数字だけでよい

FMT=数字(FORMAT文の文番号)

REC=数字(レコード番号)

END=数字(文番号.ファイルの終了を検知したら移動)

ERR=数字(文番号.エラー時に移動)

IOSTATはOPEN文と同じ


REWIND(UNIT)

ファイルの先頭に戻る

SEQUENTIALファイル用


BACKSPACE(UNIT)

1つ前のレコードに戻る


ENDFILE(UNIT)

ファイル終了記録が書き込まれる



プログラム例

(入出力プログラムは,処理系により微妙にことなるので,常に細心の注意が必要である)


c file1

parameter(n=10)

c

open(1,file='file1.dat',status='unknown')

do 10 i=1,n

write(1,*) i

10 continue

close(1)

c

write(*,*) 'output1'

open(2,file='file1.dat',status='unknown')

do 20 i=1,n

read(2,*) a

write(*,*) a

20 continue

close(2)

c

write(*,*) 'output2'

open(3,file='file1.dat',status='old')

30 read(3,*,end=40) a

write(*,*) a

go to 30

40 continue

c

write(*,*) 'output3'

rewind(3)

read(3,*) a

write(*,*) a

c

backspace(3)

read(3,*) a

write(*,*) a

close(3)

stop

end



c file2

parameter(n=10)

c

open(1,file='file2.dat',access='direct',status='unknown'

1 ,recl=4)

do 10 i=1,n

write(1,rec=i) i

10 continue

close(1)

c

write(*,*) 'output1'

open(2,file='file2.dat',access='direct',status='unknown'

1 ,recl=4)

do 20 i=1,n

read(2,rec=i) k

write(*,*) k

20 continue

close(2)

c

write(*,*) 'output2'

open(3,file='file2.dat',access='direct',status='old'

1 ,recl=4)

30 write(*,*) 'input record number ?'

read(*,*) i

if(i.LE.0) go to 40

read(3,rec=i) k

write(*,*) k

go to 30

40 continue

close(3)

stop

end

ページの始めへ戻る

その他へ戻る


ご意見・ご感想はこちらまで