INTENT
Fortran のサブルーチン内の変数についていくつか質問があります。たとえば、数週間前、私は別の Fortran トピックに関する質問を投稿しました ( Fortran 90 では、テキスト ファイルに配列を行単位で書き込む良い方法は何ですか? )。返信の 1 つに、定義するコードが含まれていました。tick
とtock
コマンド。これらは、コードの実行時間を計るのに役立つことがわかりました。tick
と以下を貼り付けtock
て、簡単な例で使用して、DO
ループの時間を計ります。
MODULE myintenttestsubs
IMPLICIT NONE
CONTAINS
SUBROUTINE tick(t)
INTEGER, INTENT(OUT) :: t
CALL system_clock(t)
END SUBROUTINE tick
! returns time in seconds from now to time described by t
REAL FUNCTION tock(t)
INTEGER, INTENT(IN) :: t
INTEGER :: now, clock_rate
CALL system_clock(now,clock_rate)
tock = real(now - t)/real(clock_rate)
END FUNCTION tock
END MODULE myintenttestsubs
PROGRAM myintenttest
USE myintenttestsubs
IMPLICIT NONE
INTEGER :: myclock, i, j
REAL :: mytime
CALL tick(myclock)
! Print alphabet 100 times
DO i=1,100
DO j=97,122
WRITE(*,"(A)",ADVANCE="NO") ACHAR(j)
END DO
END DO
mytime=tock(myclock)
PRINT *, "Finished in ", mytime, " sec"
END PROGRAM myintenttest
これは、私の最初の質問につながります(以下の2番目の質問は、INTENTが明示的に指定されていないINTENT
サブルーチンまたは関数の引数/変数に関するものです):
タイマーを開始するには、 を書きます。
CALL tick(myclock)
ここmyclock
で、 は整数です。サブルーチンのヘッダーはであるため、引数としてSUBROUTINE tick(t)
ダミー整数を受け入れます。t
ただし、サブルーチン内でt
は INTENT(OUT): が与えられますINTEGER, INTENT(OUT) :: t
。どうすればいいの?私の素朴な仮定は、INTENT(OUT) は、この変数の値が変更され、サブルーチンからエクスポートされ、読み込まれないことを意味するということです。しかし、明らかt
にサブルーチンに読み込まれています。整数myclock
をサブルーチンに渡しています。t
は INTENT(OUT) として宣言されているので、それもt
入ってくるように見えるのはどうしてでしょうか?function
tock(t)
では、整数変数now
とclock_rate
に明示的に INTENT が指定されていないことに気付きました。では、これらの変数のスコープは何ですか? 関数内now
でclock_rate
のみ表示されますか? (そのような構文はありませんが、INTENT(NONE) や INTENT(LOCAL) のようなものですか?) そして、これは関数ですが、サブルーチンにも同じことが当てはまりますか? サブルーチンを書いているときに、このような「一時的な」変数を宣言したい場合があります。これは、サブルーチン内でのみ見られる変数です (たとえば、最終出力の割り当て前のステップで入力を変更するため)。これは、指定された INTENT の欠如が達成するものですか?
テキスト ( Hahn による Fortran 90 テキスト)を調べたところ、彼は引数の意図について次のように簡単に説明しています。
引数の意図。 ダミー引数は、 intent属性で指定できます。つまり、それらを入力として使用するか、出力として使用するか、またはその両方として使用するかを指定できます。
SUBROUTINE PLUNK(X, Y, Z)
REAL, INTENT(IN) :: X
REAL, INTENT(OUT) :: Y
REAL, INTENT(INOUT) :: Z
...
インテントが IN の場合、サブプログラム内で仮引数の値が変更されていない可能性があります。
インテントが OUT の場合、対応する実引数は変数でなければなりません。のような呼び出し
CALL PLUNK(A, (B), C)
(B) は式であり、変数ではありません。
インテントが INOUT の場合、対応する実引数は再び変数でなければなりません。
仮引数に意図がない場合、実引数は変数または式である可能性があります。
すべての仮引数にインテントを指定することをお勧めします。特に、すべての関数の引数にはインテント IN が必要です。インテントは、INTENT(INOUT) X、Y、Z のように別のステートメントで指定することもできます。
上記のテキストは、引数/変数のスコープについて言及していないようです。主に、サブルーチンや関数内で引数/変数の値を変更できるかどうかについて話しているようです。これは本当ですか?もしそうなら、INTENTに関するスコープについて何を仮定できますか?