Fortran-procedures

提供:Dev Guides
移動先:案内検索

Fortran-プロシージャ

*procedure* は、明確に定義されたタスクを実行し、プログラムから呼び出すことができるステートメントのグループです。 情報(またはデータ)は呼び出し側プログラムに渡され、引数としてプロシージャに渡されます。

手順の2種類があります-

  • 関数
  • サブルーチン

関数

関数は、単一の数量を返すプロシージャです。 関数は引数を変更しないでください。

返される数量は*関数値*と呼ばれ、関数名で示されます。

  • 構文 *

関数の構文は次のとおりです-

function name(arg1, arg2, ....)
   [declarations, including those for the arguments]
   [executable statements]
end function [name]

次の例は、area_of_circleという名前の関数を示しています。 半径rの円の面積を計算します。

program calling_func

   real :: a
   a = area_of_circle(2.0)

   Print* , "The area of a circle with radius 2.0 is"
   Print *, a

end program calling_func


! this function computes the area of a circle with radius r
function area_of_circle (r)

! function result
implicit none

   ! dummy arguments
   real :: area_of_circle

   ! local variables
   real :: r
   real :: pi

   pi = 4 *atan (1.0)
   area_of_circle = pi* r**2

end function area_of_circle

上記のプログラムをコンパイルして実行すると、次の結果が生成されます-

The area of a circle with radius 2.0 is
   12.5663710

次のことに注意してください-

  • メインプログラムとプロシージャの両方で implicit none を指定する必要があります。
  • 呼び出された関数の引数rは、*ダミー引数*と呼ばれます。

結果オプション

返された値を関数名以外の名前で保存する場合は、 result オプションを使用できます。

次のように戻り変数名を指定できます-

function name(arg1, arg2, ....) result (return_var_name)
   [declarations, including those for the arguments]
   [executable statements]
end function [name]

サブルーチン

サブルーチンは値を返しませんが、引数を変更できます。

構文

subroutine name(arg1, arg2, ....)
   [declarations, including those for the arguments]
   [executable statements]
end subroutine [name]

サブルーチンを呼び出す

*call* ステートメントを使用してサブルーチンを呼び出す必要があります。

次の例は、引数の値を変更するサブルーチンスワップの定義と使用法を示しています。

program calling_func
implicit none

   real :: a, b
   a = 2.0
   b = 3.0

   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b

   call swap(a, b)

   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b

end program calling_func


subroutine swap(x, y)
implicit none

   real :: x, y, temp

   temp = x
   x = y
   y = temp

end subroutine swap

上記のプログラムをコンパイルして実行すると、次の結果が生成されます-

Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000

引数の意図を指定する

intent属性を使用すると、プロシージャで引数を使用する意図を指定できます。 次の表は、意図属性の値を提供します-

Value Used as Explanation
in intent(in) Used as input values, not changed in the function
out intent(out) Used as output value, they are overwritten
inout intent(inout) Arguments are both used and overwritten

次の例は、概念を示しています-

program calling_func
implicit none

   real :: x, y, z, disc

   x = 1.0
   y = 5.0
   z = 2.0

   call intent_example(x, y, z, disc)

   Print *, "The value of the discriminant is"
   Print *, disc

end program calling_func


subroutine intent_example (a, b, c, d)
implicit none

   ! dummy arguments
   real, intent (in) :: a
   real, intent (in) :: b
   real, intent (in) :: c
   real, intent (out) :: d

   d = b *b - 4.0* a * c

end subroutine intent_example

上記のプログラムをコンパイルして実行すると、次の結果が生成されます-

The value of the discriminant is
   17.0000000

再帰的手続き

再帰は、プログラミング言語で同じ関数内の関数を呼び出すことができる場合に発生します。 関数の再帰呼び出しと呼ばれます。

プロシージャがそれ自体を直接または間接的に呼び出す場合、再帰的プロシージャと呼ばれます。 このタイプのプロシージャは、宣言の前に recursive という語を先行して宣言する必要があります。

関数が再帰的に使用される場合、 result オプションを使用する必要があります。

以下は、再帰的な手順を使用して、指定された数値の階乗を計算する例です-

program calling_func
implicit none

   integer :: i, f
   i = 15

   Print *, "The value of factorial 15 is"
   f = myfactorial(15)
   Print *, f

end program calling_func

! computes the factorial of n (n!)
recursive function myfactorial (n) result (fac)
! function result
implicit none

   ! dummy arguments
   integer :: fac
   integer, intent (in) :: n

   select case (n)
      case (0:1)
         fac = 1
      case default
         fac = n *myfactorial (n-1)
   end select

end function myfactorial

内部手続き

プロシージャがプログラム内に含まれる場合、プログラムの内部プロシージャと呼ばれます。 内部手順を含むための構文は次のとおりです-

program program_name
   implicit none
   ! type declaration statements
   ! executable statements
   . . .
   contains
   ! internal procedures
   . . .
end program program_name

次の例は、概念を示しています-

program mainprog
implicit none

   real :: a, b
   a = 2.0
   b = 3.0

   Print* , "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b

   call swap(a, b)

   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b

contains
   subroutine swap(x, y)
      real :: x, y, temp
      temp = x
      x = y
      y = temp
   end subroutine swap

end program mainprog

上記のプログラムをコンパイルして実行すると、次の結果が生成されます-

Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000