5

このコードの例がc++C#で異なる動作をするのはなぜですか。

【C++の例】

int arr[2];
int index = 0;
arr[index] = ++index;

その結果はarr[1] = 1になります。

【C#の例】

int[] arr = new int[2];
int index = 0;
arr[index] = ++index;

その結果はarr[0] = 1になります。

これはとても奇妙だと思います。確かに、両方の言語がそれを異なる方法で実装するには、何らかの根拠があるに違いありません。C++/CLIは何を出力するのだろうか?

4

7 に答える 7

4

実際、あなたの C++ コードは何でもできます。arr[index] = ++index;未定義の動作を呼び出します。

于 2009-10-22T10:58:22.763 に答える
3

同じ代入内で index と ++index を使用した場合の動作は、C++ では規定されていません。それを行うことはできませんarr[index] = index + 1。その後、変数を作成してインクリメントします。さらに言えば、私のマシンの C++ コンパイラでは、arr[0] = 1 が表示され、arr[1] は変更されていません。

于 2009-10-22T10:57:57.413 に答える
1

少なくとも C++ の場合、事前にインクリメントしindexてシーケンス ポイントを介さずに使用することで、未定義の動作を呼び出しています。警告を有効にしてそのコードを GCC にフィードすると、次のように表示されます。

preinc.cpp:6: warning: operation on ‘index’ may be undefined

C#でも未定義だと思いますが、言語はわかりません。ただし、少なくとも C および C++ の場合、答えは、コードに誤りがあるため、コンパイラは問題なく何でも実行できるということです。異なるコンパイラ (または同じコンパイラ) が一貫した結果を生成する義務もありません。

于 2009-10-22T10:58:52.830 に答える
1

: @Eric Lippert回答によると、動作は C# に対して厳密に定義されているため、これに関する私の回答を言い換えさせてください。

このコード:

arr[index] = ++index;

C# コンパイラがそれを評価する方法と順序を正確に認識していても、読みにくい。この理由だけでも避けるべきです。

C# Operatorsに関するMSDN ページでは、Eric がそうではないと指摘しているにもかかわらず、この動作は未定義である可能性があると指摘しています。ドキュメントの複数のソース (ただし、これについては Eric を信頼します) が異なっているという事実も、これは放っておいたほうがよいものである可能性があることを示しています。

于 2009-10-22T10:59:27.643 に答える
0

C++ バージョンの結果は、未定義の動作を呼び出しているため、記述したとおりになるとは限りません。C++ では、その値の読み取りが書き込まれる値の決定の一部である場合、または式、読み取りと書き込み。

index式では、 の右側の結果をどこに代入するかを決定するためにの値を読み取っています=が、右側の部分式も を変更しindexます。

于 2009-10-22T10:58:45.407 に答える
-1

C# の index は値型です。つまり、値に対して操作を実行すると、値の新しいインスタンスが返されます。

これを演算子ではなく手続きと考えると、手続きは次のようになります。

public int Increment(int value)
{
   int returnValue=value+1;
   return returnValue;
}

ただし、C++ はオブジェクトの参照で機能するため、手順は次のようになります。

int Increment(int &value)
{
   value=value+1;
   return value;
}

注: オブジェクトに演算子を適用していた場合 (たとえば、++ 演算子をオーバーロードした場合)、オブジェクト型は参照として渡されるため、C# は C++ のように動作します。

于 2009-10-22T11:02:05.193 に答える