#define swap(a,b) a^=b^=a^=b
[cpp] view plain copy
#include <stdio.h>
#define swap(a,b) a^=b^=a^=b
int main(void)
{
int a=1,b=2;
int c[]={1,2};
swap(a,b);
swap(c[0],c[1]);
printf("a=%d,b=%d\n",a,b);
printf("c[0]=%d,c[1]=%d\n",c[0],c[1]);
return 0;
}
在不同的编译器下得到的结果是不一样的:
在GCC下运行结果:
a=2,b=1
c[0]=0,c[1]=1
在VC6.0环境下运行结果:
a=2,b=1
c[0]=2,c[1]=1
原因是什么呢?
对于同一变量的两次修改不能放在一个表达式里,
因为C++语言没有在同一表达式中规定运算顺序,
所以在第二次更改同一变量时不能保证取到的结果是第一次修改之后的。
语言没有规定,那么行为就是未定义的。
没有定义,是指不同编译器会出现不一样的行为,同一编译器也会出现不一样的行为。顺序是由编译器自行决定的,它可能对这组数据采用这种顺序,对另一组数据采用另一种顺序。
不同编译器的实现不同,出现的结果也会不同。
具体解释如下:
a = 1 = 0001
b = 2 = 0010
a^=b^=a^=b; //对a修改了两次
先执行 a^=b
a = 0011
再执行 b^=a
b = 0001
最后执行a^=b,即 a = a^b
这里的a不一定会取到第一次修改后的0011
也可能取到第一次修改之前的0001
如果取修改之后的,则 a=0011^0001 = 2;
如果取修改之前的,则 a=0001^0001 = 0;
所以gcc和vc编译器的结论有所不同。
|
|