2012-08-03 13 views
7

Fortran(90)で(実数)配列のディープコピーが必要ですが、参照の仕組みを完全に理解していないため、取得方法がわかりません。直感的に、私はこれは私が欲しいものを私を得ることを期待する:Fortranのディープアレイコピー

do i=1,n 
    b(i) = a(i) 
end do 

しかし、最近b(1:n) = a(1:n)は上記のコードと同等であることを私に指摘されました。直観的には、b(1:n) = a(1:n)は、b(1:n)の参照がメモリ内のa(1:n)の位置を指し示すに過ぎないと予想します。

b(1:n) = a(1:n)ディープコピーですか?どうして? b = aとは対照的に、根本的な参照で何が起こっていますか?

答えて

13

三つの方法、doループ、b(1:n) = a(1:n)b = aを参照してください、すべての等価です。アレイaの内容をアレイbにコピーします。 abは単純な配列であり、空想的なポインタなどではないので、代入a = bは基本的に数式と同じです。参考までに(ユーザーが知る必要のある)魔法はありません。そのため、Fortranは学ぶためのかなり簡単な言語です。あなたはFortranでポインタ配列を使うことができますが、これはまったく別の問題です。

M MetcalfとJ ReidのFortran 90/95で説明されているは、Fortranの言語機能に関する相談には常に参考になります。ページ48から:

3.11固有の割り当てによって

アレイ割り当て、配列式は、式の各要素が割り当てられたかのように解釈されるものと同じ形状の配列変数に割り当てることができます変数の対応する要素に追加します。例えば、宣言と

real, dimension(10, 20) :: a 

割り当て

a = a + 1.0 

i=1,2..,10j=1,2,..,20ためa(i,j) + 1.0によってa(i,j)を置き換えます。

スカラー式はsaclar値は、すべての配列要素にブロードキャストされる場合には、アレイに割り当てられてもよいことに留意されたいです。

これはすべて実際にどのように実装されているかという点では、私はあなたがあなたの疑問を抱いていると思っていますが、これはFortran標準によって完全には特定されていません。この種のことは、コンパイラ作成者がどのような最適化を行っても同じように行うことができるように、未定義のままです。たとえば、a = bという割り当てでは、bの要素がaにコピーされる順序は標準では指定されていないため、さまざまな方法で異なるコンパイラがこれを行うことができます。 abがポインタでない場合、abは別個の配列であり、一方の要素を変更しても他方の対応する要素は変更されないということです。ですから、a=bは "ディープコピー"で、これはbのすべてのアイテムをaのメモリ位置にコピーしていると考えることができます。

+0

@IanHこれは私が大したことを知っているものではないので、私は答えの配列に焦点を合わせました。興味深いのは、上記の例が派生型の場合ではなく、回答を投稿したい場合です。 – Chris

+0

そのバブルの謝罪、私が決定したのは未完成のバブルで、質問には関係がないと決めました(ポスターには特にREAL変数が記載されています)。私はそれが投稿されたことを知らなかった。 – IanH

+1

'b(1:n)= a(1:n)'と 'b = a'は等価ではありません。前者は、必要な再配分などをチェックしません。 –

6

a = bは、配列b全体をaにコピーします。 nより大きい次元の配列の一部だけが必要な場合は、添字表記a(1:n)= b(1:n)を使用できます。つまり、Fortran 90よりも高いレベルの言語です。 "a = b"はコピーであり、ポインタ "a"は演算子 "="を使用しているため、ターゲットbと関連付けません。ポインタの関連付けは=>を使用します。

編集:コピーすると、おそらくdoループと同じマシンコードで複製されます。ポインタの関連付けは、すべての配列要素を複製するdoループを実行せずに参照を行います。

を使用すると、配列のコピーに言及http://en.wikipedia.org/wiki/Fortran_95_language_features

+1

どのようにコピーしますか? 'a 'の参照をメモリ内の' b'の位置に振り替えるか、または 'b'内のすべてのアイテムのコピーをメモリ内の' a'の位置に移動することによって? – astay13

+2

@ astay13、FortranはJavaまたはC#ではありません。それは参照を持っていません。それはポインターを持っていますが、M. S. B.が指摘しているように( '='の代わりに '=>')指摘するように特別な構文を使用しています。例えば、 'gfortran'はコンテキストに応じて、' memcpy'(ビット単位のメモリコピー、非常に速い)または隠された 'DO'ループを使って配列コピーを実装します。 –

+0

@HristoIliev、はい、Javaが私の最初の言語であるので質問が来るので、参照割り当てに '= 'を使うのは慣れています。 – astay13