我尝试了一些代码来交换Java中的两个整数,而不使用第三个变量,使用XOR。
下面是我尝试过的两个交换函数:
package lang.numeric;
public class SwapVarsDemo {
public static void main(String[] args) {
int a = 2984;
int b = 87593;
swapDemo1(a,b);
swapDemo2(a,b);
}
private static void swapDemo1(int a, int b) {
a^=b^=a^=b;
System.out.println("After swap: "+a+","+b);
}
private static void swapDemo2(int a, int b) {
a^=b;
b^=a;
a^=b;
System.out.println("After swap: "+a+","+b);
}
}该代码产生的输出如下:
After swap: 0,2984
After swap: 87593,2984我很想知道,为什么这样说:
a^=b^=a^=b;和这个不一样?
a^=b;
b^=a;
a^=b;发布于 2014-02-26 14:46:48
问题是评价的顺序:
请参阅JLS section 15.26.2
首先计算左操作数以产生一个变量。如果此计算突然完成,则赋值表达式出于同样的原因突然完成;右操作数不计算,也不发生赋值。 否则,保存左操作数的值,然后计算右操作数.如果此计算突然完成,则赋值表达式出于相同的原因突然完成,并且不会发生赋值。 否则,将使用左边变量的保存值和右侧操作数的值来执行由复合赋值运算符指示的二进制操作。如果此操作突然完成,则分配表达式将基于相同的原因突然完成,并且不会发生赋值。 否则,二进制操作的结果被转换为左手变量的类型,并经过值集转换(§5.1.13)到适当的标准值集(而不是扩展指数值集),并将转换结果存储到变量中。
所以你的表情是:
a^=b^=a^=b;
ab^=a^=ba还没有应用^=b )a中换句话说,表达式等价于以下java代码:
int a1 = a;
int b2 = b;
int a3 = a;
a = a3 ^ b;
b = b2 ^ a;
a = a1 ^ b;您可以从方法的分解版本中看到这一点:
private static void swapDemo1(int, int);
Code:
0: iload_0
1: iload_1
2: iload_0
3: iload_1
4: ixor
5: dup
6: istore_0
7: ixor
8: dup
9: istore_1
10: ixor
11: istore_0 发布于 2014-02-26 14:27:05
因为a ^= b ^= a ^= b;被解析为:
a ^= (b ^= (a ^= b));可简化为:
a ^= (b ^= (a ^ b));因此,b将具有b ^ (a ^ b)值,最后a将为a ^ (b ^ (a ^ b)。
发布于 2014-02-26 14:29:35
检查操作符优先级(ref:由于搜索java操作符优先级而产生的http://introcs.cs.princeton.edu/java/11precedence/ )。这里出现了对Oracle的引用(http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html),尽管它有点密集)。
特别是,^=是从右到左(不是从左到右)处理的。
https://stackoverflow.com/questions/22044163
复制相似问题