-外部副プログラム-
Fortranプログラミング入門
副プログラムとは…
・プログラムを小さいプログラムに分割して使う機能
・単独では実行出来ない
・Fortranには関数とサブルーチンがある
プログラムにバグが出にくい!
バグが出ても,エラーになる部分が限定される!
副プログラム
1
Fortranのプログラムを構成する基本的な構成要素を
プログラム単位と呼ぶ.
・主プログラム
program文で始まる.一つのプログラムに必ず一つ.
・外部副プログラム
現在はモジュールで代替.様々な主プログラムから
呼び出せる副プログラム.
・モジュール(Fortran90から追加)
変数や副プログラムなどをまとめたもの.
プログラム単位
2
・主プログラム(program文)
内部関数
内部サブルーチン
・外部副プログラム
外部関数
外部サブルーチン
・モジュール
プログラム単位
3
今回はこれ!!
現在は推奨されていない!!
内部副プログラムとは…
・主プログラムの中に記述する副プログラム
・内部副プログラムが記述してある主プログラム以外
からは利用できない.
・主プログラムと変数が共有される
外部副プログラムとは…
・program文の外に(別ファイルにも)記述する.
・いろいろな主プログラムに利用できる.
・主プログラムと変数が共有されない
外部副プログラム
4
外部関数
5
program プログラム名
宣言文
実行文
stop
end program プログラム名
function 関数名(引数1,・・・)
宣言文
実行文
end function 関数名
主プログラムは終わり
主プログラムの外に書いたら外部関数となる!!
宣言文にimplicit none
を必ず書きましょう!!
外部サブルーチン
6
program プログラム名
宣言文
実行文
stop
end program プログラム名
subroutineサブルーチン名 (引数1,・・・)
宣言文
実行文
end subroutine サブルーチン名
主プログラムは終わり
サブルーチンも同様に…
external文
7
☆文法外部関数の戻り値の型, external 外部関数名
・外部関数を使用する際に必要.
・現在は非推奨な書き方(interface文を推奨)!!
program examp
real(8), external :: expfunc
・・・
end program examp
function expfunc(・・・) result(res)
real(8) :: res
・・・
end function
外部関数expfuncの使用を宣言!
real(8)はexpfuncの戻り値の型
外部関数(end programの後に書かれる)
expfuncの戻り値の型.これが上のexternalのreal(8)と一致!
外部サブルーチンには必要ない!!
8
例題1
rを倍精度実数型の変数とし,適当に値を代入する.そのとき,rを半径とする球の体積を計算する外部関数と外部サブルーチンを作成せよ.
例題1
P-9
9
program examp1
implicit none
real(8) :: r
real(8) :: V
real(8), external :: volfunc
r = 1d0
V = volfunc(r)
write(*,*) V
stop
end program examp1
function volfunc(r) result(V)
implicit none
real(8), intent(in) :: r
real(8) :: pi = acos(-1d0)
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
外部関数
外部関数volfuncの使用を宣言!
real(8)はvolfuncの戻り値の型
外部関数volfuncの使用!
program文の外にvolfuncを書くと外部関数になる
例題1
10
program examp1
implicit none
real(8) :: r
real(8) :: V
r = 1d0
call volsub(r,V)
write(*,*) V
stop
end program examp1
subroutine volsub(r,V)
implicit none
real(8), intent(in) :: r
real(8) :: pi = acos(-1d0)
real(8), intent(out) :: V
V = 4d0/3d0*pi*r**3
end subroutine volsub
外部サブルーチン
外部サブルーチンの場合external文は必要なし!!
program文の外にvolsubを書くと外部サブルーチンになる
例題1 : 内部関数と外部関数の比較
11
program examp1
implicit none
real(8) :: r
real(8) :: V
real(8), external :: volfunc
r = 1d0
V = volfunc(r)
write(*,*) V
stop
end program examp1
function volfunc(r) result(V)
implicit none
real(8), intent(in) :: r
real(8) :: pi = acos(-1d0)
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
外部関数program examp1
implicit none
real(8) :: r
real(8) :: V
r = 1d0
V = volfunc(r)
write(*,*) V
stop
contains
function volfunc(r) result(V)
real(8), intent(in) :: r
real(8) :: pi = acos(-1d0)
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
end program examp1
内部関数
例題1 : 内部関数と外部関数の比較
12
program examp1
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi = acos(-1d0)
real(8), external :: volfunc
r = 1d0
V = volfunc(r)
write(*,*) V
stop
end program examp1
function volfunc(r) result(V)
implicit none
real(8), intent(in) :: r
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
外部関数program examp1
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi = acos(-1d0)
r = 1d0
V = volfunc(r)
write(*,*) V
stop
contains
function volfunc(r) result(V)
real(8), intent(in) :: r
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
end program examp1
内部関数
関数の中で宣言していたpiを消して,主プログラムでpiを宣言すると…?
例題1 : 内部関数と外部関数の比較
13
program examp1
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi = acos(-1d0)
real(8), external :: volfunc
r = 1d0
V = volfunc(r)
write(*,*) V
stop
end program examp1
function volfunc(r) result(V)
implicit none
real(8), intent(in) :: r
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
外部関数program examp1
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi = acos(-1d0)
r = 1d0
V = volfunc(r)
write(*,*) V
stop
contains
function volfunc(r) result(V)
real(8), intent(in) :: r
real(8) :: V
V = 4d0/3d0*pi*r**3
end function volfunc
end program examp1
内部関数
関数の中で宣言していたpiを消して,主プログラムでpiを宣言すると…?
ERROR… OK!
主プログラムと変数を共有しない…
主プログラムと変数を共有する!!
※プログラム単位が1つ※プログラム単位が2つ
common文
14
☆文法 common /ブロック名/ 変数1, ・・・
・変数をプログラム単位をまたいで利用できるようにする・現在は非推奨な書き方(module文を推奨)!!
program examp
real(8) :: pi
common /pidata/ pi
pi = acos(-1)
・・・end program examp
subroutine expsub(・・・)real(8) :: pi
common /pidata/ pi
end function
変数piを共有できるように宣言.ブロック名は個人で決められる!!
ブロック名とpiをcommon文で書くことにより,主プログラムのpiと関連付けられる!!
15
例題2
rを倍精度実数型の変数とし,適当に値を代入する.そのとき,rを半径とする球の体積を計算する外部関数と外部サブルーチンを作成せよ.ただし,piは主プログラムで値を代入し,common文で値を共有せよ.
例題2
16
program examp2
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi
real(8),external :: volfunc
common /pidata/ pi
pi = acos(-1d0)
r = 1d0
V = volfunc (r)
write(*,*) V
stop
end program examp2
function volfunc(r) result(V)
implicit none
real(8), intent(in) :: r
real(8) :: pi
real(8) :: V
common /pidata/ pi
V = 4d0/3d0*pi*r**3
end function volfunc
変数piを共有できるように宣言.主プログラムで変数piに値を代入!!
主プログラムで値を代入したpiを利用!!
例題2
17
program examp2
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi
common /pidata/ pi
pi = acos(-1d0)
r = 1d0
call volsub(r,V)
write(*,*) V
stop
end program examp2
subroutine volsub(r,V)
implicit none
real(8), intent(in) :: r
real(8) :: pi
real(8), intent(inout) :: V
common /pidata/ pi
V = 4d0/3d0*pi*r**3
end subroutine volsub
変数piを共有できるように宣言.主プログラムで変数piに値を代入!!
主プログラムで値を代入したpiを利用!!
分割コンパイル
18
プログラム単位ごとにファイルを分けられる.
この場合コンパイルは…
gfortran bbb.f90 aaa.f90 必要なファイルを全部書く!!
aaa.f90
program aaa
implicit none
・・・stop
end program aaa
bbb.f90
function bbb(・・・)
・・・end function bbb
subroutine ccc(・・・)・・・end subroutine ccc
19
例題3
rを倍精度実数型の変数とし,適当に値を代入する.そのとき,rを半径とする球の体積を計算する外部サブ
ルーチンを作成せよ.ただし,外部サブルーチンは主プログラムと別のファイルに保存せよ.
例題3
20
program examp2
implicit none
real(8) :: r
real(8) :: V
real(8) :: pi
common /pidata/ pi
pi = acos(-1d0)
r = 1d0
call volsub(r,V)
write(*,*) V
stop
end program examp2
subroutine volsub(r,V)
implicit none
real(8), intent(in) :: r
real(8) :: pi
real(8), intent(inout) :: V
common /pidata/ pi
V = 4d0/3d0*pi*r**3
end subroutine volsub
examp3.f90 ex3sub.f90
gfortran ex3sub.f90 examp3.f90
コンパイル