以下最简单的Java代码会返回一些意外的输出。我们来看看吧。
package interchange;
final public class Main
{
public static void main(String[] args)
{
int x = 15;
int y = 20;
x^=y^=x^=y;
System.out.println("x = " + x + "; y = " + y);
}
}
上面的代码在控制台上显示以下输出。
x = 0; y = 15
如何?
答案 0 :(得分:6)
根据运算符优先级,可以像这样重写
x^=y; // 15 ^ 20 = 27, x = 27
y^=27; // 20 ^ 27 = 15, y = 15
x^=15; // 15 ^ 15 = 0, x = 0
答案 1 :(得分:3)
您基本上执行x XOR x
(因为您使用相同的操作数(y)应用xor操作两次),结果为0。
让我们一步一步评估您的表达,在您的情况下,我们必须从右到左执行以遵循优先顺序:
x^=y^=x^=y;
<=> y^x^y^x
<=> (y^y) ^ (x^x)
<=> (0) ^ (0)
<=> 0
答案 2 :(得分:1)
XOR按1 XOR 1 = 0和1 XOR 0 = 1且0 XOR 0 = 0
的规则运行如果你认为^ =是权力。
15 in binary = 01111 二进制20 = 10100
答案 3 :(得分:1)
对于在其一个或另一个操作数中出现的每个位,XOR返回true,但不是两者都返回。通过一个更简单的例子可能有所帮助:
x = 1001
y = 1110
x ^= y => 0111
y ^= x ^= y => 1001
x ^= y ^= x ^= y = 0000
请注意:
x <=> y ^= x ^= y
这意味着你最终会表现出来:
x ^= x
...必须为0,基于XOR的定义。
为了完整起见,这是使用x
和y
提供的值的工作:
x = 0000 1111
y = 0001 1011
x ^= y = 0001 0100
y ^= x ^= y => 0000 1111
x ^= y ^= x ^= y => 0000 0000
答案 4 :(得分:1)
我没有实际答案,但我认为优先权不是问题。添加括号以澄清,同样的事情发生:
// 3 2 1
x^=(y^=(x^=y));
我希望预期的内容相当于:
x^=y; //1: xor x with y, update x, return the new x;
y^=x; //2: xor y with (result of 1), update y, return the new y;
x^=y; //3: xor x with (result of 2), update x, return the new x;
我认为实际上发生的是使用初始值,这实际上意味着:
x0 = x;
y0 = y;
x = x0^y0^x0^y0; //0
y = y0^x0^y0; //15
问题是,我不确定语言规范在哪里可以找到。我最接近的是:
15.7.2 Evaluate Operands before Operation
Java编程语言也保证了运算符的每个操作数(除了 条件运算符&amp;&amp;,||和? :)似乎是完全评估 在执行操作本身的任何部分之前。