だから私はここで混乱しています。
a ^= b^c
に相当
a = a ^ (b ^ c)
それともa = (a ^ b) ^ c
?
短縮形の演算子:
LHS OP= RHS;
次のように機能します。
LHS = LHS OP RHS;
コメントで指摘されているように、実行される評価の数などに違いがあるため、 の評価で副作用が発生し始めるとLHS
、この単純な同等性はそれほど単純ではなくなります。または同等。そのため、上記の言葉を鉄に覆われたものにならないように書き直しました。
つまり、前者a = a ^ (b ^ c)
です。
「C および C++」は多くの分野をカバーしていますが、一例を挙げると、C99 標準は次のように述べています (6.5.16.2):
フォームの複合代入は、左辺値が 1 回だけ評価されるという点でのみ
E1 op= E2
、単純な代入式と異なります。E1 = E1 op (E2)
E1
C++ では、演算子のオーバーロードは、オペランドの型によっては、最初の式が他の 2 つの式のいずれとも等しくない可能性があることを意味します。ただし、組み込みの複合演算子については、同じ規則が適用されます。C++03 は言う (5.17/7):
フォームの式の動作は、1 回だけ評価されることを除いて、
E1 op= E2
と同じ です。E1 = E1 op E2
E1
a ^ (b ^ c)
C標準だけが、質問に直接答えるために必要な括弧を含めるのに苦労していることに注意してください(a ^ b) ^ c
。
しかし、ここで C++ 標準が使用しているアドホックな BNF に似た文法言語では、 のような BNF 非終端E2
記号は、それが現れる式の部分式と常に見なされると想定できると思います。左から右への結合 (および複合代入バージョンのすべての演算子は左から右への結合) を使用するとE2
、部分式ではなくなるように分割されるため、それを防ぐために十分な括弧を精神的に挿入する必要があります。
実際には、途中でトラップ表現を生成しない限り値は同じであり、それによってエラーが発生するため、XOR では問題になりません。これは、C または C++ の非 2 の補数実装で発生する可能性があり、そのような実装では、計算したくても計算できませんでした。非 2 の補数の実装はほぼ存在しませんが、標準では許可されています。a ^= b^c
a = (a^b)^c
重要なことに、 、、が整数の場合はと同等でa -= b - c
はありません。に等しい場合を除きます。a = (a - b) - c
a
b
c
c
0
XOR の真理値表について考えてみてください。
x | y | XOR
-----------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
つまり、b = 10; //1010
andc = 7; //0111
とa = 3; //0011
b ^ c = 1010 ^ 0111 = 1101
a ^ (b^c) = 0011 ^ 1101 = 1110 (14)
a ^ b = 0011 ^ 1010 = 1001
(a^b) ^c = 1001 ^ 0111 = 1110 (14)
特定の例を考えると、演算子のオーバーロードがないと仮定し、連想 XOR 演算子のみを使用すると...それは実際には問題ではありません。
少し具体的
でないこと^=
が最初に適用されるため、次のようになります。
a ^= b^c
と同等ですa = a ^ (b^c)
ここには演算子の優先順位はありません。あなたの質問は結合性についてです、そして演算子は結合性であるため、それは何の違いもありません。