交换两个变量一般会使用下面这种方法:
int a=2,b=4
int c=a
a=b
b=c
这样的教科书一样的方法是标准的。
利用异或的性质还可以使用另一种方法:
a^=b
b^=a
a^=b
这样也是正确的。
或者我们可以把它缩减成两句:
b^=a^=b
a^=b
这样也可以得到正确的结果(先不论这样对不对)。
事已至此,不妨更进一步:
a^=b^=a^=b
这样就得到了一句话交换两个元素的方法,但这样是否行得通呢?
在某c语言在线编译器中测试以下代码:
#include <stdio.h>
int main(void) {
int i=2,j=4;
i^=j^=i^=j;
printf("%d %d",i,j);
return 0;
}
结果成功交换了a和b,所以这个连续运算并赋值的语句看起来可能是正确的,但是如果使用java语言又会发生什么呢?
在eclipse中测试下面的代码:
public class Test {
public static void main(String[] args) {
int a=2,b=0;
a^=b^=a^=b;
System.out.println(a+" "+b);
}
}
结果是:a=0,b=2.
看起来应该是成功了,而且好像很厉害的样子,以防万一,我们多试一次。
public class Test {
public static void main(String[] args) {
int a=2,b=4;
a^=b^=a^=b;
System.out.println(a+" "+b);
}
}
结果依然是是:a=0,b=2.
这和说好的不一样呀,那么为什么会出现这种情况呢?
实际上,这样的代码即使在c语言中也无法保证成功(这是由编译器决定的),a^=b^=a^=b在进行最后一次计算时出了问题,在b^=a^=b运算成功后,此时b=2,a=a^b=2^2=0,虽然在前面的运算中a已经重新赋值,但实际上并没有使用新的值,而是使用了a的初始值。恐怕在这样的运算当中寄存器中暂存的结果并未及时写回内存,这就造成了寄存器和内存中同时存在两个不同值的情况,到底使用哪一个,这是编译器的事。在编程时,像这样的写法是绝对行不通的,因为你根本不知道会发生怎样奇奇怪怪无法解释的错误。而且这种写法在有些语言(比如python)中是无法编译的。