プログラムの中で何度も利用される処理がある場合は、副プログラムとしてまとめておくと便利です。また、副プログラムを利用することで、プログラム全体の見通しを良くすることができます。
fortranの副プログラムには、関数(function)とサブルーチン(subroutine)がありますが、この記事ではこれらを順に説明します。記事の最後にサンプルプログラムを掲載しています。
関数の記述ルール
関数は以下のように定義します。
関数の型 function 関数1(変数1,変数2)
__implicit none
__変数の型, intent(in) :: 変数1
__変数の型, intent(in) :: 変数2
__処理1
__関数1 = 処理1から得られた値
end function 関数1
・関数は整数型や実数型などの型宣言する必要があります。
・関数やサブルーチンに受け渡される変数のことを引数と言います。
・intent(in)は入力用引数を意味します。
・関数の最後に、関数内の処理によって得られた値を関数1に代入します。(この値を戻り値といいます)
メインプログラムからは、以下のように関数を利用します。
program main
__implicit none
__変数の型 :: 変数1
__変数の型 :: 変数2
__変数の型 :: 変数3
__関数の型 :: 関数1
__変数1、2の値設定
__変数3 = 関数1(変数1,変数2)
end program main
サブルーチンの記述ルール
サブルーチンは以下のように定義します。
subroutine サブルーチン1(変数1,変数2,変数3)
__implicit none
__変数の型, intent(in) :: 変数1
__変数の型, intent(in) :: 変数2
__変数の型, intent(out) :: 変数3
__処理1
__変数3 = 処理1から得られた値
end subroutine サブルーチン1
・intent(out)は出力用引数を意味します。なお、intent(inout)の場合は入出力用引数を意味します。
・上の例では、1つの変数が出力用引数となっていますが、サブルーチンでは出力用引数の数に制限はありません。(2以上でも0でもかまわない)
メインプログラムからは、以下のようにcall文によってサブルーチンを利用します。
program main
__implicit none
__変数の型 :: 変数1
__変数の型 :: 変数2
__変数の型 :: 変数3
__変数1、2の値設定
__call サブルーチン1(変数1,変数2,変数3)
end program main
*出力用引数の数に制限がないので、サブルーチンのほうが汎用性は高いですが、関数は、y=f(x)のような、数学に近い表記ができるメリットがあるため、用途に応じて使い分けて下さい。
副プログラムのちょっとしたtips
tipsを以下に列挙します。バグの出にくいプログラムを書くときに役に立つと思うので、頭の片隅に置いておいて下さいね。
・メインプログラムと副プログラムの引数の型は一致させましょう。間違わないよう引数の型宣言はコピペしましょう。
・intent(in)やintent(out)による引数の記述方法を使いましょう。入力用引数の値を副プログラム内で変えてしまった、などのバグを発見することができます。
サンプルプログラム
サンプルプログラムを下記します。4-8行目は変数の型宣言、10-12行目は変数に初期値を代入、16-19行目は関数とサブルーチンを使用した配列の和・最小・最大の計算と出力です。Fortran90では同じ計算を組込み関数を用いて行うことができます。21-23行目は組込み関数による計算と出力です。28-37行目は配列の和を求める関数の定義、41-55行目は配列の最小・最大を求めるサブルーチンの定義です。
以下のFortranプログラムをコピペし、****.f90の名前で保存して下さい(****の部分は適当でいいです)。コピペが面倒な場合は、こちらからダウンロードして下さい(右クリックメニューから保存)。→ sample09.f90
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | program sample09 implicit none !-------------------------------------------------------------------- integer, parameter :: n = 3 integer :: i real(8) :: x(1:n) real(8) :: xsum real(8) :: xmin, xmax !-------------------------------------------------------------------- x(1) = 10.0d0 x(2) = 20.0d0 x(3) = 30.0d0 write(*,'(a,3f5.1)') 'x(i) = ', (x(i), i = 1, 3) !-------------------------------------------------------------------- ! 関数とサブルーチンを使用した配列の和・最小・最大の計算と出力 write(*,'(a,f5.1)') 'sum of x = ', xsum(x,n) ! 関数による和の計算と出力 call minmax_x(xmin,xmax,x,n) ! サブルーチン呼び出し write(*,'(a,f5.1)') 'min of x = ', xmin ! 最小値出力 write(*,'(a,f5.1)') 'max of x = ', xmax ! 最大値出力 ! f90の組込み関数を使用した配列の和・最小・最大の計算と出力 write(*,'(a,f5.1)') 'sum of x = ', sum(x) write(*,'(a,f5.1)') 'min of x = ', minval(x) write(*,'(a,f5.1)') 'max of x = ', maxval(x) end program sample09 !******************************************************************** ! 配列の和を求める関数 real(8) function xsum(x,n) implicit none integer, intent(in) :: n real(8), intent(in) :: x(1:n) integer :: i xsum = 0.0d0 do i = 1, n xsum = xsum + x(i) end do end function xsum !******************************************************************** ! 配列の最小・最大を求めるサブルーチン subroutine minmax_x(xmin,xmax,x,n) implicit none integer, intent(in) :: n real(8), intent(in) :: x(1:n) real(8), intent(out) :: xmin, xmax integer :: i xmin = x(1) do i = 2, n if (x(i) < xmin) xmin = x(i) end do xmax = x(1) do i = 2, n if (x(i) > xmax) xmax = x(i) end do end subroutine minmax_x |
使い方は、前記事と同様に、****.f90を以下の****.batにドラッグ&ドロップするだけです。
64bit用 → comp_exe_64.bat
32bit用 → comp_exe_32.bat
こんな画面が出たでしょうか?出ていれば正常終了です。10-12行目の値を変えて、色々試してみて下さい。
→ 次の記事へ(モジュール)
← 前の記事へ(配列(1)-基本操作)
目次(Fortran90)