または、
~と部屋とYシャツと私
または、
~と酒と泪と男と女
元ネタ:「比較と代入の演算子」
元ネタのコメントで永遠の18歳に怒られたので、まじめに記事にしてみます。
まず、青柳さんもコメントで指摘されてますが、C#言語仕様にすべて答えがのっています。
と、いうか、祖先のC言語からここら辺の話は変わっていないので、K&R読んでも良いかも。
# 昔は学生に訳させたものをまとめただけなので、訳が極悪だったけど、最近のはマシになったっていう噂を小耳に...
まずお題確認。
Console.WriteLine((j = i) == i);
比較演算子の左辺は、i と j どちらの値と比較しているのでしょう?
ですね。
んぢゃあ、小分けしていきましょ。まず。いっちゃん最初に評価されるのから
って、どれが一番先なん?って疑問がわきますよね。
で、チェックするのがこちら
演算子の優先順位と結合規則
参考ページ:「7.2.1 演算子の優先順位と結合規則」
今回は()が使われているので、=と==の優先順位は気にしなくてよいとして、問題は結合規則になります。
- 代入演算子を除くすべての二項演算子の結合規則は、左から右です。つまり、演算は左から右に実行されます。たとえば、x + y + z は (x + y) + z と評価されます。
- 代入演算子と条件式演算子 (?:) の結合規則は右から左です。つまり、演算は右から左に実行されます。たとえば、x = y = z は x = (y = z) と評価されます。
とありますので、==の場合は左辺の(j=i)から評価されるということが分かります。
ぢゃ、お次は(j=i)を詳しく見ていきましょう
代入の仕組み
参考ページ:「7.13.1 単純代入」
代入は右辺の値が左辺の変数(もしくはそれに準じるもの)に格納されます。ここは良いとして、ポイントは
単純代入式の結果は、左オペランドに代入される値です。結果は左オペランドと同じ型で、常に値として分類されます。
の一文です。
ここでいう「単純代入式の結果」というのが(j=i)の最終的な値です。
誤解を恐れずに言い方を変えると、メソッドの戻り値のようなものとも考えられるでしょうか。
その「単純代入式の結果」は「左オペランドに代入される値」と言っています。
つまり、(j=i)が評価される時点で右辺の i に入っていた値ということになります。
なのでRさんの疑問に対する答えは i ってことになります。
で、怒られた補足のコメントをつけた理由が以下。
オトンとオトンと、ときどき、オトン
で、比較の部分に来るわけですが。
# あ、小題はみゃったく関係ナッシングです。(^^ゞ
参考ページ:「7.9 関係演算子と型検査演算子」
あ、参考ページといいつつ、ここには大したこと書いていません。
ここで再度押さえておきたいのは結合規則です。
参考ページ:「7.2.1 演算子の優先順位と結合規則」
- 代入演算子を除くすべての二項演算子の結合規則は、左から右です。つまり、演算は左から右に実行されます。たとえば、x + y + z は (x + y) + z と評価されます。
- 代入演算子と条件式演算子 (?:) の結合規則は右から左です。つまり、演算は右から左に実行されます。たとえば、x = y = z は x = (y = z) と評価されます。
大事なことなので、2回引用しました。
で、ここでは答えを明かさず、新たなお題。(^.^)
新たなお題
1: int i = 1;
2: int j = 0;
3: Console.WriteLine(j);
4: Console.WriteLine((j = i++) == i);
5:
6: i = 1;
7: j = 0;
8: Console.WriteLine((j = ++i) == i);
ここで4行目と8行目の結果はどうなるでしょうか?
理由も含めてね。
# ちなみに3行目は最適化防止です。
エンジョイ!(^_-)