副プログラム

プログラムの中で何度も利用される処理がある場合は、副プログラムとしてまとめておくと便利です。また、副プログラムを利用することで、プログラム全体の見通しを良くすることができます。

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


sample09


こんな画面が出たでしょうか?出ていれば正常終了です。10-12行目の値を変えて、色々試してみて下さい。


→ 次の記事へ(モジュール)
← 前の記事へ(配列(1)-基本操作)
目次(Fortran90)

スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です