1

慣れていない方法でポインター演算を使用するコードを理解しようとしています。コードのある時点で、これに遭遇しました:

complex<double> **P, *p_row, result=complex<double>(0,0);
P=new complex<double>*[n];
for(i=0;i<n;i++) P[i]=new complex<double>[n];

for(i=0,p_row=*P;i<n;i++,p_row+=n) result+=log(*(p_row+i));

P が行列の場合、これは P の対角要素の対数を加算するように見えますが、上記の最後の行は次と同等ではないことがわかります

for(i=0;i<n;i++) result+=log(P[i][i]);

ここで何が起こっているのかの説明を探していますが、見つかりません。また、問題のコードは最終的に正しい結果をもたらすようです (これはモンテカルロの一部です)。何か案は?

4

2 に答える 2

2

あなたが投稿したコードは間違っています。未定義の動作を引き起こします。

例えば。2 回目の反復では、p_rowです(*P)+n*Pは size の配列を指しているnため、コードが を読み取るとき、*(p_row+i)配列の末尾を超えて読み取ります。

最後の行は、行列が単一の連続配列に格納されていることを前提としているようです (例: 行メジャー)。ただし、それはによって初期化さPれることを意味します。complex<double>*P = new complex<double>[n*n];

于 2012-10-26T16:30:38.033 に答える
2

with ループp_row+=nは未定義の動作を示します。これは、3 行目のループによって行われた割り当てが連続していると仮定しているためですが、ほとんどすべての実装ではそうではありません。

コードP[i][i]は正しい結果を取得します。n*n単一のショットで要素を割り当ててから、それらをpループ内に分割することで、他のコードを修正できます。

于 2012-10-26T16:31:01.203 に答える