2012-01-30 30 views
9

私は正式な概念としてのしっかり把握していたことはありませんC order of operations.C言語の右から左および左から右への連想の影響は何ですか?

一つのことがが結合性である私は、スクリプト言語を書くプロセスでだと私は(かなりよく標準化された)をコピーします。左から右への演算子グループと右から左への演算子グループは何故ですか?

ルールがすべて左から右またはそれとは逆の場合、コード行がどのように異なって見えるかの例をいくつか教えてください。それとも、なぜ私は恣意的な選択だと思われるかのように、結合性はそれがどういうものなのか、彼らはそれが理由があると思います。

また、ちょうど注意することは、私はちょうど左から右へ(またはその逆)の任意の例を考えることはできませんどのような関連性の手段、知って丸め累積その他の選択肢

+0

これはすばらしい質問です。また、[理由 - その代入 - オペレータ - 左手側に割り当てる](http://programmers.stackexchange.com/questions/98406/why-does-the-assignment-operator-左手側に割り当てる) – nawfal

答えて

13

ほとんどの場合、各演算子はその演算子にとって最も合理的な結合性を持っています。

すべての非代入2項演算子は、左から右への結合性を持っています。これは、英語が左から右に読み込まれているという明白な理由から、x + y + zの評価が読み方と一貫しているために便利です。さらに、算術演算子の場合、セマンティクスは数学の演算子の使用法から期待されるものと一致します。

代入演算子は右から左への結合性を持ちます。左から右への割り当ては、奇妙で予期しないセマンティクスを持ちます。たとえば、x = y = zは、元の値がzであるyyの元の値を持つxになります。 3つの変数はすべて、式が完了した後に同じ値を持つことが期待されます。 ~!xで、!xが最初に評価されるように

接頭辞単項演算子は、オペランドに最も近いの演算子が最初に評価されているので、理にかなって右から左結合性を、持っている、そして~が結果に適用されます。実際には、は本当にです。左から右への結合性を適用した接頭辞演算子は、~!x~xを評価してから!を適用すると、式についての考え方と完全に逆ですほとんどの人が表現について考える方法...)。

+1

Cでは、代入演算子の左から右への結合は '(x = y)= z'がエラーであるのと同じ理由で' x = y = z'をエラーにします。 – caf

+0

@caf:本当ですが、演算子の結合性を変更することを検討している場合は、演算子式の値カテゴリを変更することも考えられます。 –

0

よりも優れています通常は答えです。

ただし、>>と< <は、それらがどのように構成されているか< 2 >> 3のように構成する必要があります。

6

例:

5 - 4 - 3 
(5 - 4) - 3 = -2 // left association is correct 
5 - (4 - 3) = 4 // right is incorrect 

a == b == c // What does this equal? 
      // It is common to have == be non-associative because of this. 

x = y = z 
x = (y = z) // right association is correct, sets x and y 
(x = y) = z // left is incorrect, does not set y 

ほとんどの演算子は、数学からの連想性を継承します。ビット単位は算術演算子と見なすことができ、したがって連想を残します。

~!-x = ~(!(-(x))) 

他の方法は、postfixのない限り、あまり意味がありません。そのように、それのグループがあるため

単項は右結合です。

+1

私は非結合性が嫌いです。私の考えでは、 'a == b == c'は'(a == b)== c'( 'a == b'のブール結果を' c'と比較する)か、 Pythonは 'a == b ')&&(b' == c)'の中に 'b '= bを置きます。 –

2

厄介な演算子はべき乗です(例:Pythonの場合は**、Rの場合は^、haskellの場合)。ほとんどの言語、パーサーなど3 ** 3 ** 33 ** (3 ** 3)と表示されます。私は個人的にはこれが正しい解釈だと思っていますが、最近オクターブとmatlabの両方で(3 ** 3) ** 3と計算されています。

これは、指数演算子を持たないため、Cでは問題ありません。代わりにpow関数を呼び出し、明示的にpow(3,pow(3,3))またはpow(pow(3,3),3)のいずれかを指定する必要があります。

+2

これはCobolとFortranでの右結合:http://www.fortran.com/F77_std/rjcnf0001-sh-6.htmlです。数学的に言えば、これは正しい解釈です。 – EJP

関連する問題