int x = 2010;
int y = 2012;
y^=(x^= (y^= x));
System.out.println("x= " + x + "; y= " + y);
输出结果为x= 2012; y= 0 int x = 2010;
int y = 2012;
int z = (x^= (y^= x));
y^=z;
System.out.println("x= " + x + "; y= " + y);
输出结果为x= 2012; y= 2010为什么我把(x^= (y^= x))用z表示以后得到的结果就改变了??
这是为什么呢?
int y = 2012;
y^=(x^= (y^= x));
System.out.println("x= " + x + "; y= " + y);
输出结果为x= 2012; y= 0 int x = 2010;
int y = 2012;
int z = (x^= (y^= x));
y^=z;
System.out.println("x= " + x + "; y= " + y);
输出结果为x= 2012; y= 2010为什么我把(x^= (y^= x))用z表示以后得到的结果就改变了??
这是为什么呢?
第一种情况下y^=(x^= (y^= x));中间的计算结果,即第一次运算y^= x后变量y(这时为2)的值被最后一次的运算结果给覆盖掉了,并没有得到保存。最后 得到的y=0.
第二种情况z = (x^= (y^= x));因为y只被赋值一次,所以y此时等于2,z=2012. y^=z后,y=2010
int x = 2010;
int y = 2012;
// y=(x^= (y^= x))^ y;
y^=(x^= (y^= x));
System.out.println("x= " + x + "; y= " + y);
这2种表达式运算之后为什么打印结果不一样吗?
int x = 2010;
int y = 2012;
y^=(x^= (y^= x));对应的jvm指令码解释如下:
0: sipush 2010
3: istore_1 //为x变量赋值
4: sipush 2012
7: istore_2 //为y变量赋值
8: iload_2 //stack0=2012
9: iload_1 //stack1=2010
10: iload_2 //stack2=2012
11: iload_1 //stack3=2010
12: ixor //stack3^stack2, 结果stack2=2
13: dup //stack3=2
14: istore_2 //y=2, stack3被清空
15: ixor //stack2^stack1, 结果stack1=2012
16: dup //stack2=2012
17: istore_1 //x=2012, stack2被清空
18: ixor //stack1^stack0, 结果stack0=0
19: istore_2 //y=0, stack0被清空
刚好之前遇到个帖子, 研究了下这道题, java中的陷阱:http://topic.csdn.net/u/20100517/00/68e3a8c7-0d61-4366-8c5b-96393fcc6a74.htmlwingardium 的做法很对, 通过机器码解释, 但是我没怎么懂.我用的debug, 发现, 其实这儿的原因在于:
首先, y^=(x^= (y^= x)); 等价于 y=y^(x^= (y^= x))
在y=y^(x^= (y=y^x))里面, 注意红色的y和蓝色的y值是不一样的, 因为在等式计算之前, 红色的y就已经被赋值成了2012,而蓝色的y计算后是6(相当于这个是中间结果).也就是说: 你把y^=(x^= (y^= x)); 换成 y1^= x1;y1=y1^(x1^= y1);
结果也是对的.也许还是解释得有点晕,呵呵,想通了就简单了.
C/C++ y^=(x^= (y^= x)) 可以实现x,y互换
现在越来越多的人开始研究什么JAVA内存管理啊,什么奇奇怪怪的东西,反倒把最应该掌握的东西丢在一边。
就象鲁迅写的笔下的孔已己,知道茴香豆的茴字有几种写法,又有什么意义呢?你做项目的时候,会让你写这种代码吗?还不如把这些时间多花在多项目,实践上,除非您是想搞科研——OK,当我没说。我觉得,用JAVA没超过5年的(牛人可以短一些时间),不要去接触那些和项目无关的东西,这对你们来说没意义。