Fortran-procedures
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