プログラム中で同じ処理を何度も行いたい場合がよくある.そのたびごとに同じプログラムを何度も書くのは馬鹿げている.同じ処理はサブルーチンとして外部手続きとしておくと都合がよい.
サブルーチンを呼び出す側のプログラムは「主プログラム(main program)」と呼ばれる.サブルーチンは主プログラムのend文以降に,主プログラムと独立に次のように書く. subroutine文以下end subroutineまでがサブルーチンである.
program example
implicit none
double precision :: d,f,g
......
call S(f,g,d)
......
end program example
subroutine S(a,b,c)
implicit none
double precision intent(in) :: a
double precision intent(out) :: b
double precition intent(inout) :: c
......
......
return
end subroutine
| サブルーチン文 | S(a,b,c) | サブルーチンの定義をおこなう |
| S | サブルーチン名:英文字で始まる31文字以内の英数字 |
|---|---|
| a,b,c | 仮引数:使う変数は型宣言すること | intent(in) :: a | aが入力引数であることを明示 |
| intent(out) :: b | bが出力引数であることを明示 |
| intent(inout) ::c | cが入出力引数であることを明示 |
| call 文 | call S(f,g,d) | サブルーチンを呼び出す |
| f,g,d | 実引数:仮引数と順序, 型を一致させる必要あり |
|---|
サブルーチンはend subroutine文で終わらなければならない.サブルーチンから,呼ばれた場所に強制的に戻るには
return
を書く.return文は何個あってもよい(end subroutineは一個:end subroutine文のみでreturn文がない場合はend subroutineにおいて呼ばれた場所に戻る).それでは次のプログラム
を入力して実行してみよう.
プログラム2-1
program example1
implicit none
double precision :: a,b,c
a = 1.D0
b = 2.D0
call wa(a,b,c)
write(*,*) c
end program example1
subroutine wa(a,b,c)
implicit none
double precision, intent(in) :: a,b
double precision, intent(out) :: c
double precision :: d ! サブルーチン内のみで使われる変数にはintentをつけない
c = a + b
d = a * c ! このdの値はメインプログラムに渡されない
return
end subroutine
呼ぶ方(call wa(a,b))と呼ばれる方(subroutine wa(a,b))の引数は順序,個数,型を一致させなければならない.逆に言うと,引数の個数,型が一致していれば名前は違っていてもよい.サブルーチンを使う場合は, サブルーチンとの変数, 配列のやりとりに注意すること.どれが入力でどれが出力かを頭にいれてプログラムを作成すること. カッコの中に含まれている変数配列のみがメインプログラムとやりとりされることに注意.
次のプログラムは何をするのか考えてみよう.
program example2
implicit none
double precision :: a,b,c,d,e
a=1.D0
b=2.D0
d=3.D0
e=4.D0
call wa(a,b,c)
write(*,*) c
call wa(d,e,c)
write(*,*) c
end program example2
subroutine wa(a,b,c)
implicit none
double precision, intent(in) :: a,b
double precision, intent(out) :: c
c=a+b
end subroutine
プログラム2-3
program error1
implicit none
double precision :: a,b
a=1.D0
b=2.D0
call sum(a,b)
write(*,*) b
end program error1
subroutine sum(a,b)
implicit none
double precision, intent(in) :: a
double precision, intent(in) :: b
b=a+b
end subroutine sum
プログラム2-4
program error2
implicit none
double precision :: a,b
a=1.D0
b=2.D0
call sum(a,b)
write(*,*) b
end program error2
subroutine sum(a,b)
implicit none
integer, intent(inout) :: a,b
b=a+b
end subroutine sum
プログラム2-5
program error3
implicit none
double precision :: a(2),b
a(1)=1.D0
a(2)=2.D0
b=0.D0
call sum(a,b)
write(*,*) b
end program error3
subroutine sum(a,b)
implicit none
double precision, intent(in) :: a
double precision, intent(out) :: b
b=a(1)+a(2)
end subroutine sum
プログラム2-3を,a,bの積を計算するサブルーチンに書きかえよ. これを用いて変数a,bの積(答えは2.D0)を算出せよ.
変数a,bに代入された値を入れ替えるサブルーチンswap(a,b)を作成せよ.サブルーチンに変数a,bが代入され,実行後はa,bの中身が入れ替わる.a, bは実数とする.