サーチ…


備考

関数サブルーチンはモジュールと組み合わせて、 プログラムをユニットに分割するツールです。これにより、プログラムはより読みやすく管理しやすくなります。これらのユニットのそれぞれは、理想的にはコンパイルして単体でテストできるコードの一部と考えることができます。主プログラムは、そのような副プログラム(関数またはサブルーチン)を呼び出して(または呼び出して)、タスクを達成することができます。

関数とサブルーチンは次の点で異なります。

  • 関数は単一のオブジェクトを返し、通常は引数の値を変更しません(つまり、数学関数のように動作します)。
  • サブルーチンは通常、より複雑なタスクを実行し、引数(存在する場合)やその他の変数(サブルーチンを含むモジュールで宣言された変数など)を通常変更します。

関数とサブルーチンは総称してプロシージャ名の下にあります 。 (以下では、手順があることをしても技術的にあれば、「起動」の同義語として「コール」動詞を使用するcall編ですsubroutineのに対し、S functionの代入の右辺として、または式で表示されます。)

関数の構文

関数は、いくつかのタイプの構文を使用して記述できます

function name()
  integer name
  name = 42
end function
integer function name()
  name = 42
end function
function name() result(res)
  integer res
  res = 42
end function

関数は、 関数の結果を通して値を返します。 functionステートメントにresult節がないかぎり、関数の結果は関数と同じ名前になります。 resultは、関数の結果はresultによって与えられます。上の最初の2つの例では、関数の結果はnameで与えられてnameます。 3回目はres

関数の実行中に関数の結果を定義する必要があります。

関数はいくつかの特別なプレフィックスを使うことを許します。

関数とは、この関数に副作用がないことを意味します。

pure real function square(x)
  real, intent(in) :: x
  square = x * x
end function

元素関数は、スカラー演算子として定義されているが、機能要素ごと適用される場合には実引数としてアレイで起動することができます。 impure接頭辞(Fortran 2008で導入されている)が指定されていない限り、 要素関数も純粋な関数です。

elemental real function square(x)
  real, intent(in) :: x
  square = x * x
end function

返信文

return文は、関数とサブルーチンを終了するために使用できます。他の多くのプログラミング言語とは異なり、戻り値の設定には使用されません。

real function f(x)
  real, intent(in) :: x
  integer :: i

  f = x

  do i = 1, 10

    f = sqrt(f) - 1.0

    if (f < 0) then
      f = -1000.
      return
    end if

  end do
end function

この関数は反復計算を実行します。 fの値が負の値になると、関数は-1000を返します。

再帰的プロシージャ

Fortranの関数とサブルーチンは、直接的または間接的に自身を再度呼び出す場合、 再帰的に明示的に宣言する必要があります。したがって、フィボナッチシリーズの再帰的な実装は、次のようになります。

recursive function fibonacci(term) result(fibo)
  integer, intent(in) :: term
  integer :: fibo

  if (term <= 1) then
    fibo = 1
  else
    fibo = fibonacci(term-1) + fibonacci(term-2)
  end if
  
end function fibonacci

他の例では階乗を計算することができます:

recursive function factorial(n)  result(f)
  integer :: f
  integer, intent(in) :: n
  
  if(n == 0) then
    f = 1
  else
    f = n * f(n-1)
  end if
end function factorial

関数を直接再帰的に参照するには、その定義にresultサフィックスを使用する必要があります。関数がrecursiveかつelemental recursiveであることは不可能です。

ダミー引数の意図

サブルーチンまたは関数内の仮引数のintent属性は、その意図された使用を宣言します。構文は次のいずれかです。

intent(IN)
intent(OUT)
intent(INOUT)

たとえば、次の関数を考えます。

real function f(x)
  real, intent(IN) :: x

  f = x*x
end function

intent(IN)は、(ポインタではない)仮引き数xが関数全体またはその初期化の間に決して定義されないか、または定義されないことを指定します。ポインタ仮引数が属性intent(IN)持つ場合、これはその関連付けに適用されます。

intent(OUT)は、サブプログラムの呼び出し時に仮引数が定義されなくなり(実行時に設定されるデフォルトの初期化で派生型のコンポーネントを除く)ことを意味します。ダミー引数として渡される実際の引数は、定義可能でなければなりません。名前付き定数またはリテラル定数または式を渡すことはできません。

前述と同様に、ポインタ仮引数がintent(OUT)の場合、ポインタの関連状態は未定義になります。実際の引数はポインタ変数でなければなりません。

intent(INOUT)は、実引数が定義可能であり、プロシージャからのデータの受け渡しとデータの返却の両方に適していることを指定します。

最後に、仮引数にはintent属性がないかもしれません。そのような仮引数は、渡された実際の引数によってその使用が制限されます。

たとえば、

integer :: i = 0
call sub(i, .TRUE.)
call sub(1, .FALSE.)

end

subroutine sub(i, update)
  integer i
  logical, intent(in) :: update
  if (update) i = i+1
end subroutine

引数iintent属性を持たないので、メインプログラムのサブルーチンコールの両方が可能です。

プロシージャの参照

有用な関数またはサブルーチンを参照する必要があります。 call文でサブルーチンが参照される

call sub(...)

式の中の関数。他の多くの言語とは異なり、式は完全な文を構成しないので、関数参照は代入文でよく見られるか、または他の方法で使用されます。

x = func(...)
y = 1 + 2*func(...)

参照されるプロシージャを指定する方法は3つあります。

  • プロシージャまたはプロシージャのポインタの名前
  • 派生型オブジェクトの手続きコンポーネント
  • 型バインドされたプロシージャーバインディング名

最初のものは次のように見ることができます

procedure(), pointer :: sub_ptr=>sub
call sub()   ! With no argument list the parentheses are optional
call sub_ptr()
end

subroutine sub()
end subroutine

最後の2つは

module mod
  type t
    procedure(sub), pointer, nopass :: sub_ptr=>sub
  contains
    procedure, nopass :: sub
  end type

contains

  subroutine sub()
  end subroutine

end module

use mod
type(t) x
call x%sub_ptr()   ! Procedure component
call x%sub()       ! Binding name

end

仮引数を持つ手続きの場合、参照には対応する引数が必要ですが、オプションの仮引数が与えられない場合もあります。

サブルーチンを考えてみましょう

subroutine sub(a, b, c)
  integer a, b
  integer, optional :: c
end subroutine

これは、以下の2つの方法で参照することができます

call sub(1, 2, 3)   ! Passing to the optional dummy c
call sub(1, 2)      ! Not passing to the optional dummy c

これはいわゆる位置参照です。実際の引数は、引数リスト内の位置に基づいて関連付けられます。ここで、ダミーa1に関連付けられ、 b2関連付けられ、 c (指定された場合)には3が関連付けられます。

あるいは、プロシージャが明示的なインタフェースを使用できる場合には、 キーワード参照を使用できます

call sub(a=1, b=2, c=3)
call sub(a=1, b=2)

これは上記と同じです。

ただし、キーワードを使用すると、実際の引数は任意の順序で提供される可能性があります

call sub(b=2, c=3, a=1)
call sub(b=2, a=1)

位置とキーワードの参照を両方とも使用することができます

call sub(1, c=3, b=2)

キーワードの最初の出現に続くすべての引数に対してキーワードが与えられている限り

call sub(b=2, 1, 3)  ! Not valid: all keywords must be specified

キーワード参照の値は、複数のオプションの仮引数がある場合に特に顕著です。上記のサブルーチン定義の場合には、 bもオプションです。

call sub(1, c=3)  ! Optional b is not passed

型付きプロシージャまたは渡された引数を持つコンポーネント・プロシージャ・ポインタの引数リストは、別々に考慮されます。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow