a^=b^=a^=b交换数组中两个数探究

转自: http://blog.youkuaiyun.com/guoxuequan/article/details/8039836

#define swap(a,b) a^=b^=a^=b

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #define swap(a,b) a^=b^=a^=b  
  3. int main(void)  
  4. {  
  5.     int a=1,b=2;  
  6.     int c[]={1,2};  
  7.     swap(a,b);  
  8.     swap(c[0],c[1]);  
  9.     printf("a=%d,b=%d\n",a,b);  
  10.     printf("c[0]=%d,c[1]=%d\n",c[0],c[1]);  
  11.     return 0;  
  12. }  


在不同的编译器下得到的结果是不一样的:

在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编译器的结论有所不同。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值