むりせず♪なまけず? ~ぷろくらすてぃねいたーの言い訳雑記~

よた ときどき .NET  by 刈歩 菜良 CTP

目次

ニュース

C# VB.NET掲示板
C#, VB.NET 掲示板

わんくま同盟ブログ
わんくま同盟ブログ

Web アプリケーションを簡単編集できる無償ツール WebMatrix ダウンロードはこちら

あわせて読みたい

日記カテゴリ

書庫

Blog 利用状況

C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン

または、

~と部屋とYシャツと私

または、

~と酒と泪と男と女

元ネタ:「比較と代入の演算子

 

元ネタのコメントで永遠の18歳に怒られたので、まじめに記事にしてみます。

 

まず、青柳さんコメントで指摘されてますが、C#言語仕様にすべて答えがのっています。

と、いうか、祖先のC言語からここら辺の話は変わっていないので、K&R読んでも良いかも。

# 昔は学生に訳させたものをまとめただけなので、訳が極悪だったけど、最近のはマシになったっていう噂を小耳に...

まずお題確認。

Console.WriteLine((j = i) == i);

比較演算子の左辺は、i と j どちらの値と比較しているのでしょう?

ですね。

 

んぢゃあ、小分けしていきましょ。まず。いっちゃん最初に評価されるのから

って、どれが一番先なん?って疑問がわきますよね。

で、チェックするのがこちら

 

演算子の優先順位と結合規則

参考ページ:「7.2.1 演算子の優先順位と結合規則

今回は()が使われているので、=と==の優先順位は気にしなくてよいとして、問題は結合規則になります。

    • 代入演算子を除くすべての二項演算子の結合規則は、左から右です。つまり、演算は左から右に実行されます。たとえば、x + y + z(x + y) + z と評価されます。
    • 代入演算子と条件式演算子 (?:) の結合規則は右から左です。つまり、演算は右から左に実行されます。たとえば、x = y = zx = (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 = zx = (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行目は最適化防止です。

エンジョイ!(^_-)

投稿日時 : 2009年4月20日 23:12

Feedback

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 0:11 aetos

> ここは良いとして、ポイントは
> 単純代入式の結果は、左オペランドに代入される値です。結果は左オペランドと同じ型で、常に値として分類されます。
> 一文です。

先生、それは二文です。

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 9:14 刈歩 菜良 CTP

シャノンさん
> 先生、それは二文です。

( ̄□ ̄;)!!

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 9:15 774RR

C++ の場合 JIS X3014:2003 5 式 3
(副作用完了点の間で)直前の値は次に格納すべき値を決定するためだけにアクセスされる。
# 誤訳っすね。原文
ISO/IEC 14882:1998 5-4
prior value shall be accessed only to determine the value to be stored

とあるので ((j=++i)==i) も ((j=i++)==i) も未定義なコード断片となりマッスル
要するに誤ったコードであり結果の保証は何一つ無い。

C# にも類似の文言、無いっすか?

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 10:10 R・田中一郎

えムナウさんは、永遠の28歳です。

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 10:19 ちゅき


と、永遠の18歳がおっしゃってます^^;
#って、永遠の18歳はRセンセであってましたっけ……。IIJIMAS先生だったような気もする^^;

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 18:36 刈歩 菜良 CTP

774RRさん
ん?
原文がどこに落ちているのかわからないので、なんともですが、文脈から言うとprior valueってのは代入演算子の左辺ってことぢゃないかしら?
だとすると、問題なっすぃんぐのような...

なにか、大きな勘違いしてるかしら?

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 18:40 刈歩 菜良 CTP

Rさん
> えムナウさんは、永遠の28歳です。
あ゛っ!そーだった。
ま、本人からクレーム入ってないからいいや。
(*^_^*)

ちゅうきっつあん
> ↑
> と、永遠の18歳がおっしゃってます^^;
なつかしひ~。
もう2,3年前のネタですよね。
(^.^)


てか、誰もお題に答えてくれないわ。
(;O;)

つまんなかったかしら...

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 21:12 774RR

C# ではなくて C++ で恐縮なのですが、ここでの prior value は「副作用発生前の値」の意
副作用の発生前の値は、当該副作用の結果を求めるため以外に使っちゃだめということで
i=i+1; や i+=i; や j/=i++; はOK
j=i++ +i; とかはだめ
っつーことでござんす

((j=i++)==i) にて発生する副作用は2つ
j=i で j が変化する副作用
i++ で i が変化する副作用
C/C++ の場合この2つの副作用が具体的にいつ発生するかは決まっていないわけですな
i++ で i が変化する前に ==i が評価されるか
i++ で i が変化した後に ==i が評価されるか
は言語規格書が定めていないわけです(説明のための語弊あり)

C/C++ での設問の答えは「未定義動作を含むため答えられない」となります

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 22:08 刈歩 菜良 CTP

774RRさん

詳細なご説明をありがとうございます。
でも、まだ???だなぁ。

2つ疑問があって、まず、英文の解釈。
> to determine the value to be stored
があるので、「あぁー、これは左辺が++xみたいになってちゃだめだよってことなのかしら?」と、単純に思っちゃいました。
原文ってどっかに落ちてないでしょうか?
# グーグル先生に聞きましたが、ようみつけんかったです。(T_T)

で、もうひとつは私なりの解釈を記事にするとき明らかにしますね。

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/21 23:41 774RR

ISO/JIS の規格文書なので、正式版は買ってください(はーと)
ISO/IEC 14882 現在の版は 2003
http://webstore.ansi.org/ で $80 (約8000円)
http://www.iso.ch/ で CHF380 (約3万円)

正式採択前のドラフトでよければ(正式版と異なる可能性があり:未確認)
14882 FDIS で検索してみたらヒットすると思うです
# ドラフトなんぞを信じると痛い目にあいますが・・・

# re: C#の演算子の優先順位と結合規則と代入の仕組みとオカンとボクと、時々、オトン 2009/04/22 1:27 刈歩 菜良 CTP

774RRさん

情報ありがとうございます。
ドラフト見っけました。
http://www.cs.technion.ac.il/users/yechiel/CS/C++draft/ISO-CPP-body.pdf
で、該当場所はP63の4ですよね。

だとしたら、やはりprior valueは左辺の代入される側の変数を表してるっぽいです。

774RRさんも例に出されていましたが、代入演算子を使っていて左辺にきている変数の値を右辺にある計算式の中で変更するような処理をしている場合の結果は未定義ということみたいです。

これは比較演算子には適用されないような気がします。
その理由が、
> only to determine the value to be stored
の部分です。

これは、「代入する場所を識別されるためだけに(使われるべき)」という意味だと思うので、少なくともここの一文は代入演算子に関してだけ言及しているのかと...

他の英文は今ちょっとそこまで余裕がないので読めてないです。
_(._.)_

# Finding this post ha 2014/05/11 6:53 Nerice

Finding this post has aneswred my prayers

# Finding this post ha 2014/05/11 6:54 Nerice

Finding this post has aneswred my prayers

# ロレックスコピー 2023/06/03 3:30 coxAcquic

弊社は海外安心と信頼のプラダ 時計 コピーです。2023 新作が満載!皆様を歓迎して当店をご光臨賜ります。ロレックス時計コピー,パネライ時計コピー,ウブロ時計コピー ,ブライトリング時計コピー,IWC時計コピー,フランクミュラー時 計コピー,ショパール時計コピー,フェラーリ時計コピー,グラハム 時計コピー,ハリー ウィンストン時計コピー等。サイトは世界一流ブランド }}}}}}
https://www.bagssjp.com/product/detail-715.html
https://www.bagssjp.com/product/detail-8380.html
https://www.bagssjp.com/product/detail-11297.html
https://www.bagssjp.com/product/detail-8528.html
https://www.bagssjp.com/menu/menu_pinpai-1-109.html

# Being a customer, I fіnd it helpful Ьecause іts main benefit Phased-Array probe liees іn its efficiency. It іs more efficient tһan օther NDT techniques ɑnd provides accurate resultѕ іn a short period of tіmе. 2023/08/01 15:37 Ᏼeing a customer, Ӏ find it helpful Ьecause іts ma

Bеing a customer, ? find it helpful bеcause its main benefit Phased-Array probe
lies ?n its efficiency. It is mоre efficient t?an other NDT techniques
and ρrovides accurate result? ?n a short period oof time.

タイトル
名前
Url
コメント