2017-07-18 9 views
1

私はずっと前に、FORTRANではすべてが価値によって渡されたと言われました。したがって、私はこれを行う必要があるだろう(mySubroutine提供適切に他の場所で定義される):数量はどのようにFortranで参照されますか?

double precision :: myArray(2) 
myArray(1:2) = (/ 2.3d0, 1.5d0 /) 
CALL mySubroutine(myArray) 

しかし、私はまた、プログラムのコンパイルと私は必要とせずに、この

CALL mySubroutine((/ 2.3d0, 1.5d0 /)) 

をすれば期待通りに実行されることを発見仲介配列myArrayを定義します。参考までにmyArraymySubroutineに渡していると思いました。第2版​​では何が起こっていますか?コンパイラはサブルーチン呼び出しをアンパックして、一時変数を宣言して参照渡しするだけですか?

+1

Fortranでは、デフォルトですべてが参照渡しされます(または、動作するかのように動作します)。後者の場合は、コンパイラが効果的に一時配列を作成し、参照を渡すことが正しいです。 'mysubroutine'が引数を変更すると、最初のケースでは' myarray'が変更され、2番目のケースでは予測できないことが起こることに注意してください。 – agentp

答えて

3

多くの場合、参照渡しと値渡しでコールするFortranプロシージャを分類することはあまり役に立ちません。その詳細については、this onethis oneなどの質問に答えてください。簡単に言えば、プロシージャ内の変数への変更が、プロシージャが参照された変数に反映されるようなプロシージャ参照が一般的です。場合によっては、コンパイラーはコピーイン/コピーアウトを選択することができ、他のコンパイラーは効果的に行う必要があります。同様に、仮引数のvalue属性は、匿名コピーを作成することを指定します。この質問は少し違う何かを追加し

は、このような

call mySubroutine([2.3d0, 1.5d0]) ! Using F2003 array constructor syntax 

のような表現を使用している一時変数を作成するコンパイラですか?

確かに、これはおそらく用語の緩みですが、確かに変数は含まれていません。 [2.3d0, 1.5d0]は変数ではなく、式です。重要なことは、プロシージャ内で変更できない(変数定義コンテキストに現れる)ことを意味します。式ではなく(一時的)変数を用いた場合に適用される制限は、次のとおり

  • 発現に関連する仮引数がintent(inout)又はintent(out)属性を有していなくてもよいです。
  • 仮引数にインテント属性がない場合、関連付けられた実際の引数が式である場合、その引数は変更されません。

ここで仮引数にvalue属性がある場合、プロシージャの効果は参照される方法と同じです。

結論として、プログラムは中間変数の代わりに式でも同様に動作します。そうでない場合は、Fortranの一部の側面に違反しているためです。それがどのように動作するかは、プログラマではなくコンパイラの問題です。

+0

あなたの役に立つ答えをありがとう!私がこの質問をする動機は、このコードは何度もループする関数の一部であり、 'mySubroutine'に式を直接挿入することで時間を削っているのだろうかと思っています(' intent (in) ')。そうすれば、myArrayは何度も何度も再初期化されることはありません。 – QuantumDot

関連する問題