-8

所以我在这里很困惑,是否:是

 a ^= b^c 

相当于

 a = a ^ (b ^ c) 

或者是a = (a ^ b) ^ c吗?

4

4 回答 4

5

任何短格式运算符:

LHS OP= RHS;

非常像:

LHS = LHS OP RHS;

正如评论中所指出的,完成的评估次数等存在差异,因此如果您在评估 时开始产生副作用,那么LHS这种简单的等价就不再那么简单了。或同等学历。这就是为什么我重新措辞上述内容以使其不那么铁板一块。

所以是前者,即a = a ^ (b ^ c)

于 2012-10-02T12:40:27.993 回答
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 的特殊语法语言中,BNF 非终结符E2总是被认为是它出现的表达式的子表达式。所以在一个案例中具有从左到右的关联性(并且所有具有复合赋值版本的运算符都从左到右关联),这将拆分E2以使其不再是子表达式,我们必须在心里插入足够的括号来防止这种情况发生。

在实践中,异或无关紧要,因为无论如何值都是相同的,除非您在此过程中生成陷阱表示,这会导致错误。这可能发生在 C 或 C++ 的非 2 补码实现上,并且即使它想要也无法计算这种情况的实现。非 2 的补码实现几乎不存在,但标准允许它们。a ^= b^ca = (a^b)^c

重要的a -= b - c是,等价于, ,是整数a = (a - b) - c的情况。除非等于。abcc0

于 2012-10-02T13:15:02.793 回答
2

想想异或真值表,试一试,这有关系吗?

x | y | XOR
-----------
0 | 0 |  0
1 | 0 |  1
0 | 1 |  1
1 | 1 |  0

所以如果你说b = 10; //1010and c = 7; //0111anda = 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)

于 2012-10-02T12:55:20.427 回答
1

这里没有运算符优先级。您的问题是关于关联性的,并且由于运算符是关联的,因此没有任何区别。

于 2012-10-02T12:45:21.653 回答