[解決済み】i = 0のとき、なぜ(i += i++)は0になるのですか?
疑問点
次のようなコード(コンソールアプリケーションとして使用可能)を考えてみましょう。
static void Main(string[] args)
{
int i = 0;
i += i++;
Console.WriteLine(i);
Console.ReadLine();
}
の結果は
i
は0です。私は2を期待していました(私の同僚の何人かもそうでした)。おそらく、コンパイラが何らかの構造を作り、その結果
i
がゼロになる。
i はすでに 1 なので、1 に 1 を足していることになります。明らかに、これは起こっていないことです。
コンパイラが何をしているのか、あるいは実行時に何が起こっているのか、説明できますか?なぜ結果が0になるのでしょうか?
免責事項: このコードを使用しない(そしておそらく使用すべきではない)ことは絶対に認識しています。私は決して使いません。それでも、なぜこのような動作をするのか、何が起きているのかを正確に知ることは興味深いことです。
解決方法は?
これです。
int i = 0;
i += i++
しているように見ることができます(以下は総花的な表現です)。
int i = 0;
i = i + i; // i=0 because the ++ is a postfix operator and hasn't been executed
i + 1; // Note that you are discarding the calculation result
実際に起こることはもっと複雑です。MSDNを見てみてください。 7.5.9 Postfix のインクリメントとデクリメント演算子 :
x++またはx--という形式の後置加算・減算操作の実行時処理は、以下のステップで構成される。
xが変数に分類される場合。
- x が評価され、変数が生成される。
- xの値が保存される。
- 保存された x の値を引数として、選択された演算子が呼び出されます。
- 演算子から返された値は、x の評価で指定された場所に保存されます。
- 保存されたxの値が演算の結果となる。
ただし
の優先順位は
を使用すると、後置修飾子
++
が発生します。
以前
+=
の前の値なので)結局使われないままです。
i
が使用されます)。
の分解をより徹底して行う。
i += i++
を構成している部分まで知る必要があります。
+=
と
++
は、そのように見えてもアトミックではない(つまり、どちらも単一の操作ではない)。これらの実装には、一時変数、コピーした
i
操作の前に、それぞれの操作に対して1つずつ。(ここでは
iAdd
と
iAssign
に使用される一時的な変数に使用されます。
++
と
+=
をそれぞれ参照)。
ということは、より身近なところでは、次のようになります。
int i = 0;
int iAdd = i; // Copy of the current value of i, for ++
int iAssign = i; // Copy of the current value of i, for +=
i = i + 1; // i++ - Happens before += due to order of precedence
i = iAdd + iAssign;
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] C#でHashtableよりDictionaryが好まれる理由とは?
-
[解決済み] URLのPath.Combineは?
-
[解決済み] .NET String.Format()で数値の千の位にカンマを追加する
-
[解決済み] NULL-COALESCING 演算子のカスタム暗黙変換の不思議な挙動
-
[解決済み】.NETにゾンビは存在するのか......?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み] [Solved] 不正な文字列値: '\xEFxBFxBD' for column
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】「namespace」なのに「type」のように使われる。