FORTRAN プログラミング入門 第11 回主プログラ...
Transcript of FORTRAN プログラミング入門 第11 回主プログラ...
木村拓馬
FORTRANプログラミング入門–第 11回主プログラムと副プログラム (2)–
木村拓馬
2014年6月 7日 19:58
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 1/22
木村拓馬
.本日は..
......
サブルーチン
外部サブルーチンと分割コンパイル
内部サブルーチン
配列を引数とするサブルーチン
(INTENT)
(COMMON文)
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 2/22
木村拓馬
副プログラム
副プログラムには次の2つがある1.
関数(FUNCTION)式の中に関数名を書いて呼び出す.
値を 1つ返す.
サブルーチン(SUBROUTINE)CALL文を用いて呼び出す.値を返さないで,引数の値を書き換える.
関数とサブルーチンでは,呼び出し方法とデータの受け渡し方法が違う.
図 5:関数. X の値を渡すと F(X) の値を返す
図 6:サブルーチン. S を呼び出すと X や Y の値を書き換える(書き換えないものもある)
1規格では”関数副プログラム”と”サブルーチン副プログラム”だが長いので省略.
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 3/22
木村拓馬
例:ヘロンの公式の処理(pr3.3.f90 .. Link )を関数として定義する..三角形の3辺の長さを入力したら面積 (ex10.1.f90)..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, S
REAL, EXTERNAL :: F
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
S = F(A, B, C)
WRITE(*,*) ’AREA: ’, SEND PROGRAM
REAL FUNCTION F(A, B, C)IMPLICIT NONEREAL :: A, B, C, PP = (A+B+C)/2.0F = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END FUNCTION F
.
......( 一つのファイル (ex10.1.f90) に記述したときは,これまでと同様にコンパイルできる )
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 4/22
木村拓馬
外部関数の分割コンパイル2
例:ex10.1.f90 の主プログラムと副プログラムを別々のファイルに保存し,まとめてコンパイル.ex10.1main.f90..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, SREAL, EXTERNAL :: FWRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, CS = F(A, B, C)WRITE(*,*) ’AREA: ’, S
END PROGRAM
.ex10.1func.f90..
......
REAL FUNCTION F(A, B, C)IMPLICIT NONEREAL :: A, B, C, PP = (A+B+C)/2.0F = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END FUNCTION F
.コンパイルのときは必要なファイルを全部書けばよい(他の方法は講義「FORTRAN プログラミング」で紹介予定)..
......[user@host␣˜/FPR1]$g95␣ex10.1main.f90␣ex10.1func.f90 [user@host␣˜/FPR1]$g95␣-o␣ex10.1␣ex10.1main.f90␣ex10.1func.f90
2複数のファイルに分割されたプログラムをコンパイルすることを分割コンパイルという
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 5/22
木村拓馬
サブルーチン(SUBROUTINE)
サブルーチンは大きく分けて次の2つ
内部サブルーチン
他のプログラム単位の一部分としてサブルーチンを記述
CONTAINSで区切って定義
外部サブルーチン
プログラム単位として独立(他のプログラム単位に含まれない)
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 6/22
木村拓馬
サブルーチンの宣言
サブルーチンは,次のようにして宣言する([ ]の中は省略できる).
.
......
SUBROUTINEサブルーチン名 (引数 1,引数 2,引数 3,· · · ) [IMPLICIT NONE] サブルーチン中で使う変数の宣言
……………
[RETURN] END [SUBROUTINE [サブルーチン名]]
サブルーチン名の付け方は変数と同じ (英字で始まる 31文字の英数字と下線)
RETURN文は,副プログラムの実行を終了し,副プログラムを呼び出したプログラムに戻るための実行文.
RETURN文は任意の場所で使うことができる.END行直前の RETURN文は省略できる (が省略しないことを推奨)
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 7/22
木村拓馬
サブルーチンの呼び出しサブルーチンを呼び出す側では,次のようにする.
.
......
PROGRAM MAIN (外部関数等の場合はここが関数名等となる) [IMPLICIT NONE] 変数宣言
……………
CALL サブルーチン名 (引数 1,引数 2,引数 3,· · · ) ……………
END PROGRAM MAIN (外部関数等の場合はここが関数名等となる)
関数では結果は 1つしか受け取れなかったが,サブルーチンでは複数の結果を受け取ることができる.
実引数と仮引数は型,順序,個数が同じでなければならない.
仮引数が変数名の時は,実引数は定数,変数名,配列要素名,算術式を用
いることができる.
仮引数が配列名の時は,実引数も配列名とし,その形状 (次元と大きさ)は同じでなければならない.
変数,配列はプログラム単位ごとに独立であるため,実引数と仮引数に用
いる変数名,配列名は,同じでも異なっていても構わない.
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 8/22
木村拓馬
外部サブルーチンの例
例:ヘロンの公式の処理(pr3.3.f90 .. Link )を外部サブルーチンとして定義する..三角形の3辺の長さを入力したら面積 (ex11.1.f90)..
......
!----- 三角形の三辺の長さから面積を求める-----PROGRAM HERON
IMPLICIT NONEREAL :: A, B, C, S
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB(A, B, C, S)
WRITE(*,*) ’AREA: ’, SEND PROGRAM
SUBROUTINE SUB(A, B, C, S)IMPLICIT NONEREAL :: A, B, C, P, SP = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINE
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 9/22
木村拓馬
外部サブルーチンの分割コンパイル3
例:ex11.1.f90 の主プログラムと副プログラムを別々のファイルに保存し,まとめてコンパイル.ex11.1main.f90..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, SWRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, CCALL SUB(A, B, C, S)WRITE(*,*) ’AREA: ’, S
END PROGRAM
.ex11.1sub.f90..
......
SUBROUTINE SUB(A, B, C, S)IMPLICIT NONEREAL :: A, B, C, P, SP = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINE
.コンパイルのときは必要なファイルを全部書けばよい(他の方法は講義「FORTRAN プログラミング」で紹介予定)..
......[user@host␣˜/FPR1]$g95␣ex11.1main.f90␣ex11.1sub.f90 [user@host␣˜/FPR1]$g95␣-o␣ex11.1␣ex11.1main.f90␣ex11.1sub.f90
3複数のファイルに分割されたプログラムをコンパイルすることを分割コンパイルという
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 10/22
木村拓馬
例:ヘロンの公式の第 1式と第 2式を別々のサブルーチンで定義..ex11.2.f90..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, P, S
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB1(A, B, C, P)CALL SUB2(A, B, C, P, S)
WRITE(*,*) ’AREA: ’, SEND PROGRAM
SUBROUTINE SUB1(A, B, C, P)IMPLICIT NONEREAL :: A, B, C, PP = (A+B+C)/2.0RETURN
END SUBROUTINE
SUBROUTINE SUB2(A, B, C, P, S)IMPLICIT NONEREAL :: A, B, C, P, SS = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINE
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 11/22
木村拓馬
内部サブルーチン
サブルーチンも,内部関数と同様に CONTAINSで区切ることにより,他のプログラム単位の一部分として関数を記述できる.
.
......
PROGRAM MAIN [IMPLICIT NONE] 変数宣言 …………… CALLサブルーチン名 (実引数をカンマを区切って列挙) …………… CONTAINS SUBROUTINEサブルーチン名 (仮引数をカンマで区切って列挙) [IMPLICIT NONE] サブルーチン中で使う変数の宣言 …………… [RETURN] END SUBROUTINE [サブルーチン名] END PROGRAM MAIN
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 12/22
木村拓馬
例:ヘロンの公式の処理(pr3.3.f90 .. Link )を内部サブルーチンとして定義する..ex11.3.f90..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, S
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB(A, B, C, S)
WRITE(*,*) ’AREA: ’, SCONTAINS
SUBROUTINE SUB(A, B, C, S)IMPLICIT NONEREAL :: A, B, C, P, SP = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINEEND PROGRAM
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 13/22
木村拓馬
内部サブルーチンのルール
上位の(関数を含む)プログラム単位で宣言した変数とその値を共有でき
る(注意!)
上位のプログラム単位で宣言した変数名と同じ名前の変数を,その内部サ
ブルーチンでのみ有効な変数として宣言できる.
内部サブルーチンの中に再度 CONTAINS文を書くことはできない.
内部サブルーチンから同じプログラム単位中 (同じ親プログラム内)の別の内部副プログラムを呼び出すことができる.
各内部サブルーチンにおいて,最後の「END SUBROUTINE」は省略できない.
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 14/22
木村拓馬
例:親プログラムで使われている変数名,配列名などは内部サブルーチンでも有効.ex11.4.f90..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, S
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB()
WRITE(*,*) ’AREA: ’, SCONTAINS
SUBROUTINE SUB()IMPLICIT NONEREAL :: PP = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINEEND PROGRAM
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 15/22
木村拓馬
配列を引数とするサブルーチン
結果を配列で受け取りたい場合,
外部関数では INTERFACE文が必要であったが, 外部サブルーチンでは必要ない.
例:配列の各要素を2倍する外部サブルーチン..ex11.5.f90..
......
PROGRAM VEC_SUBIMPLICIT NONEINTEGER :: A(3)=(/1, 2, 3/), B(3)CALL SUBR(A ,B)WRITE(*,*) B
END PROGRAM VEC_SUB
SUBROUTINE SUBR(A, B)IMPLICIT NONEINTEGER :: A(3), B(3), IDO I = 1, 3
B(I) = A(I) * 2END DORETURN
END SUBROUTINE SUBR
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 16/22
木村拓馬
参考文献
[1] JIS X 3001-1:2009 (プログラム言語 Fortran –第 1部:基底言語)
[2] 戸川隼人:ザ・Fortran90/95,サイエンス社(1999)
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 17/22
木村拓馬
Appndix
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 18/22
木村拓馬
INTENT~安全な引数の受け渡し~INTENT 属性:仮引数の授受特性を指定する.ex11.3.f90+INTENT 属性(ex11.6.f90)..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, S
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB(A, B, C, S)
WRITE(*,*) ’AREA: ’, SCONTAINS
SUBROUTINE SUB(A, B, C, S)IMPLICIT NONE
REAL, INTENT(IN) :: A, B, CREAL, INTENT(OUT) :: SREAL :: P
P = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINEEND PROGRAM
.
......← 入力専用の変数.値を変更するとエラー← 出力専用の変数.値を設定しないと警告
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 19/22
木村拓馬
異なるプログラム単位間での変数名・値の共有 変数,配列はプログラム単位ごとに独立であり,値は共有されない. 変数・値を共有したい場合は,内部副プログラムに書き換えるか,モジュールやCOMMON 文を用いて変数名・値を共有する45.
COMMON文は,物理的な記憶場所のブロックを指定する.これを共通ブロックと呼ぶ.共通ブロックは,プログラム中のどの有効域からも参照可能.したがって大域的なデータ参照が可能になる.
.
...... COMMON [/共通ブロック名 /]変数のリスト
共通ブロック名は省略可能.ただし,複数の共通ブロックを並べて宣言する場合,”/”は省略できない. 例) COMMON /BLOCKA/ A, B, C(10) COMMON A, B, C(10) COMMON /BLOCKA/ A, /BLOCKB/ B COMMON /BLOCKA/ A, // B
共通ブロック名が一致すれば,その中の変数名・配列名はプログラム単位間で名前が異なってもよいが,順序や型,配列の形状 (次元と大きさ)が異なってはならない.
4モジュールは新しい機能で,COMMON 文よりも便利.最近はモジュールの使用が推奨されているようなので,COMMON 文は付録で紹介する程度にしておく.
5モジュールは秋学期の「FORTRAN プログラミング」で扱う予定.本講義では扱わない
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 20/22
木村拓馬
例:COMMON 文で変数を共有.ex11.7.f90..
......
PROGRAM HERONIMPLICIT NONEREAL :: A, B, C, SCOMMON /VAR/ A, B, C, S
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB
WRITE(*,*) ’AREA: ’, SEND PROGRAM
SUBROUTINE SUBIMPLICIT NONEREAL :: A, B, C, P, SCOMMON /VAR/ A, B, C, SP = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINE
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 21/22
木村拓馬
例:説明はしないけど,モジュールで変数を共有する例.ex11.8.f90..
......
MODULE VARIABLEIMPLICIT NONEREAL :: A, B, C, S
END MODULE VARIABLE
PROGRAM HERONUSE VARIABLE
WRITE(*,*) ’INPUT THE THREE SIDE LENGTHS OF TRIANGLE’READ(*,*) A, B, C
CALL SUB
WRITE(*,*) ’AREA: ’, SEND PROGRAM
SUBROUTINE SUBUSE VARIABLE
REAL :: PP = (A+B+C)/2.0S = (P*(P-A)*(P-B)*(P-C))**0.5RETURN
END SUBROUTINE
FORTRAN プログラミング入門,–第 11 回主プログラムと副プログラム (2)– 22/22