R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

インクリメント演算子を前後に置いたときの優先順位(その2)

http://blogs.wankuma.com/rti/archive/2009/06/08/174492.aspx
インクリメント演算子を前後に置いたときの優先順位

懲りずに

インクリメント演算子の前後置き

について、しつこくエントリーを上げます。
はっきし言って駄文ですw

前回のコメントで aetos さんがいいこと言った。


[引用]

# re: インクリメント演算子を前後に置いたときの優先順位 2009/06/09 11:51 aetos
なんか違和感がある。

int i = ++x; の場合、++x の式の値は x + 1 です。
int i = x++; の場合、x++ の式の値は x です?

C# の言語仕様では、代入 = の優先順位は最低です。
なので、前置の場合は、まず優先順位の高い ++x が行われ、続いて = が行われます。
後置の場合は? なんだか i = x が先に行われ、後で x++ が行われているようにも見えます。

式の値の決定のタイミングを考えると、前置でも後置でも = より先です。
前置は言うに及ばず、後置は、式の値を x と決定してから代入が行われています。加算は代入の前でも後でも構いません(既に式の値は決定しているので、代入の結果は変化しません)。

うーん? 関係あるようなないような?

[/引用]



あると思います!

同じ優先順位の演算子が複数ある式の場合は、代入演算子と複合代入演算子の優先順位は右から、それ以外の演算子は左から評価されます。
でも、後置き演算子は、代入の後に実行されています。

そこで、前回のエントリーにもあった以下のリンク先を見てみます。

http://msdn.microsoft.com/ja-jp/library/aa691323.aspx
7.2.1 演算子の優先順位と結合規則


[引用]

セクション カテゴリ 演算子 
7.5  基本式 x.y  f(x)  a[x]  x++  x--  new
typeof  checked  unchecked
 
7.6  単項式 +  -  !  ~  ++x  --x  (T)x

[/引用]


メソッドの引数に後置きインクリメント(デクリメント)演算子を用いた時と同じ挙動になる理由としては、メンバアクセス演算子や、要素アクセス演算子などと同列だからという理由が考えられるんですよね。
でも、基本式の演算の評価順序は最優先になってます。
基本式を最優先にしないと次のように記述できませんからねぇ・・・


var i = Value[1] + value[2] + GetValue(a++);


実際に実行すると、上記の演算式の評価は、次の順序になると思います。

Value[1] の値の取得
Value[2] の値の取得
Value[1] に Value[2] の値を加算
GetValue(a) を実行して結果を取得
Value[1] + Value[2] の計算結果に、GetValue(a) によって得た値を加算
a 値をインクリメント

ほらね、何か変なの~ ・・・・と、話が最初に戻る訳ですよw

【上記の疑問は解決しますた】

コメントにて、えムナウ先生と青柳さんの二人で解説してもらって上記の疑問は解決しますた。
なるほど、なるほど~(U字工事調でお願いします)

Value[1] の値の取得
Value[2] の値の取得
Value[1] に Value[2] の値を加算
a 値を保存
a 値をインクリメント←インクリメント演算子は、ここで実行されている!
GetValue(保存した a の値) を実行して結果を取得
Value[1] + Value[2] の計算結果に、GetValue(a) によって得た値を加算

投稿日時 : 2009年6月9日 14:06

Feedback

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/09 14:57 えムナウ

Value[1] の値の取得
Value[2] の値の取得
Value[1] に Value[2] の値を加算
a 値を保存
a 値をインクリメント
GetValue(保存したa) を実行して結果を取得
Value[1] + Value[2] の計算結果に、GetValue(保存したa) によって得た値を加算

じゃないといけないはずです。

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/09 15:03 えムナウ

static void Main(string[] args)
{
 int[] value = {1,2,3};
 var a = 4;
 var i = value[1] + value[2] + GetValue(a++) + GetValue(a++);
 Console.WriteLine(i);
}

static int GetValue(int a)
{
 return a;
}

value[1] + value[2] = 5
一回目 GetValue(a++) = 4
二回目 GetValue(a++) = 5 (既に一回目でインクリメントされている)
合計14になるはずです。

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/09 15:10 青柳 臣一

えムナウさんのおっしゃる通りですね。

7.5.9 後置インクリメント演算子と後置デクリメント演算子
http://msdn.microsoft.com/ja-jp/library/aa691363(VS.71).aspx

にあるとおりで、後置++は 「評価した結果を保存して、インクリメントして、保存したやつを結果とする」 という演算子です。
結果を返した後にインクリメントするわけじゃありません。

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/09 15:16 R・田中一郎

えムナウ さん
青柳 臣一 さん

把握!

>a 値を保存
>a 値をインクリメント

なるほど、なるほど~(U字工事調でお願いします)
ここ数日間のモヤモヤが解消しました。
ありがとうございました。

#明日のネタにしようっと~

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/10 9:01 774RR

実際の副作用が発生するタイミングって C# では決められているんだっけ?

C/C++ では副作用が具体的に発生するタイミングは決められていません。
i=a++ + ++b; なるコードがあったとき決められているのは
・a の新値は、以前の a の値 +1
・b の新値は、以前の b の値 +1
・i の新値は、変更前の a の値+変更後の b の値
という3点だけであって、変数の値が更新される具体的順序は決まっていません。

C# の仕様書探してみたけどよくわからんかった・・・

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/10 9:19 R・田中一郎

>実際の副作用が発生するタイミングって C# では決められているんだっけ?

僕も詳しいことがわからずに、ここで疑問だけ放り投げている立場なのですw

>i=a++ + ++b; なるコードがあったとき決められているのは
>・a の新値は、以前の a の値 +1
>・b の新値は、以前の b の値 +1
>・i の新値は、変更前の a の値+変更後の b の値
>という3点だけであって、変数の値が更新される具体的順序は決まっていません。

MSDN と今回の件で判明した(というかMSDNが読み切れていなかったのですが)ことからわかったことによると、C# では次の順に演算が行われる筈です。

a 値を保存
a++ を評価
++b を評価
保存されたa値に評価後のbを加算
i に代入

演算子の優先順位は、以下の通りです。

a++ は基本式で最優先
++b は単項式で2番目の優先順位
+ は算術二項演算子で3番目の優先順位
= は代入演算子で4番目の優先順位

僕が疑問なのは、上記の式を次のようにした場合の挙動です。

i = ++a + b++;

MSDN の解説によると b++ 次の順になる筈なんですが、検証ができないとゆー

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2009/06/10 9:20 R・田中一郎

・・・ひょっとして逆汗という手があるかな

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2011/01/24 19:00 𢭆

モダンコンバット2
おもろいね!

# re: インクリメント演算子を前後に置いたときの優先順位(その2) 2011/01/24 19:02 jun_




























俺もモダンコンバット2やってる!
面白い!!!!!!!!















# pTiRoWIBYOTrUw 2011/12/16 1:21 http://www.heartlandvetsupply.com/

Heartfelt thanks..!

# tlHtoyhbCeyfEJe 2011/12/22 19:47 http://www.discreetpharmacist.com/

nFcRnL Yeah? I read and I understand that I do not understand anything what it is about:D

タイトル
名前
Url
コメント