所以我在这里感到困惑,确实: 是
a ^= b^c
相当于
a = a ^ (b ^ c)
还是a = (a ^ b) ^ c
?
答案 0 :(得分:5)
任何简短形式的运算符:
LHS OP= RHS;
非常像:
LHS = LHS OP RHS;
正如评论中指出的那样,评估的数量也存在差异等等,所以如果你在LHS
的评估中开始产生副作用,那么这种简单的等价就不再那么简单了。或同等学历。这就是为什么我重新措辞上面的内容,使其不那么铁。
所以它是前者,即a = a ^ (b ^ c)
。
答案 1 :(得分:3)
“C和C ++”涵盖了很多方面,但举一个例子,C99标准说(6.5.16.2):
E1 op= E2
形式的复合赋值不同于简单 赋值表达式E1 = E1 op (E2)
仅限于左值E1
只评估一次。
在C ++中,运算符重载意味着第一个表达式可能与其他两个表达式都不相同,具体取决于操作数的类型。但对于内置复合运算符,适用相同的规则。 C ++ 03说(5.17 / 7):
E1 op= E2
形式的表达式的行为等同于E1 = E1 op E2
,但E1
仅评估一次。
请注意,只有C标准才会包含必要的括号来直接回答您的问题:它名义上是a ^ (b ^ c)
而不是(a ^ b) ^ c
。
但是我认为我们可以假设在C ++标准在这里使用的类似BNF的特殊语法语言中,像E2
这样的BNF非终端始终被认为是表达式的子表达式它出现在。所以在从左到右相关性的情况下(并且所有具有复合赋值版本的运算符从左到右关联),这将分割E2
使得它不再是一个子表达式,我们必须在精神上插入足够的括号来防止这种情况。
在实践中,对于XOR来说并不重要,因为无论如何值都是相同的,除非在此过程中生成陷阱表示,这会导致错误。这可能发生在C或C ++的非二进制补码实现上,并且即使它想要,也可以不计算a ^= b^c
为a = (a^b)^c
的实现。非二进制补码实现几乎不存在,但标准允许它们。
重要的是,在a -= b - c
,a = (a - b) - c
,a
为整数的情况下,b
不等同于c
。除非c
等于0
。
答案 2 :(得分:2)
想想XOR真值表,尝试一下,甚至重要吗?
x | y | XOR
-----------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
所以,如果你说b = 10; //1010
和c = 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)
答案 3 :(得分:1)
此处没有运算符优先级。你的问题是关联性,并且由于操作符是关联的,它没有任何区别。