Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1385277
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: C/C++

2015-03-01 19:04:32

     作为一名应届毕业生,在做C语言笔试的时候总是会遇到在不利用第三个变量对数值交换的笔试题,下面我就将相关的解题思路汇总一下,方便和我有同样疑惑的伙伴们理解;
     交换数值基本上可以有三种方式,
第一种:
void change(int &a,int &b){
       int temp = a;
       a = b;
       b = a;
}
第二种:
void change(int &a,int &b){
        a = a + b;
        b = a - b;
        a = a - b;
}
注意:这种方式容易造成益处,在32位系统上,int 类型占用4个字节,即:-2^16 ~ 2^16-1,
          一不小心就容易造成整形数据的溢出。
第三种:
void change(int &a,int &b){
        a ^= b;
        b ^= a;
        a ^= b;
}

        对于前两种解题方式还好理解,对于第三种方式对于我这种小白看起来就有点费解了,经过查阅资料,汇总如下:
1.异或的定义(相同为0,不同为1)
0^0 = 0
0^1 = 1
1^0 = 1
1^1 = 0

2.异或满足交换律
a^b = b^a
特殊的
0^a = a^0 = a
1^a = a^1 = ~a(表示a取反,本来该是a头上一横)
a^a = 0
a^(~a) = 1

3.异或满足结合律
(a^b)^c = a^(b^c)

由上面的定律可以简单地推出
a^b^a = a^a^b = 0^b = b
a^b^b = a^0 = a

通过上面的分析,稍微明白了点,举个例子:
int a=1,b=2;
a^=b;
b^=a;
a^=b;
cout<
代码执行后:a为2,b为1
a = 3 ^ 5;
3的二进制是0011,5的二进制是0101。异或发现两者的不同之处,所以a最终为0110b(6)。
了解了异或的基本原理后,接下来看上述的代码。
a^=b;
这一句使得a被赋值为“数值a”与“数值b”的“差异值”。
然后:b^=a;
这一句用异或利用“差异值”来还原a的数值,并赋值给b。此时b等于a先前的数值。
最后一句:a^=b;
因为a仍然保存着“差异值”,这一句通过异或使得b的初始值被还原,并赋值给a。
。。。。。
这样,异或就将a与b的数值“巧妙”地交换了……
有时候,我们总以为某些事务很神奇。实际上也只是一种自然规律罢了。

            另外,还有一种特殊情况,在两个数值相等的时候就有问题了,此时就要注意了,一定要在交换之前判断两个数是否已经相等
否则,
a ^= a;  //a = 0;
a ^= a;  //a = a;
a ^= a;  //a = 0;
所以,此时要小心

阅读(957) | 评论(1) | 转发(0) |
0

上一篇:没有了

下一篇:献给新手们——STM32学习 建议

给主人留下些什么吧!~~

cpuieng2015-06-18 11:51:49

a ^= a;  //a = 0;
a ^= a;  //a = a;  //算法里是a^=b  这时b还存的原来的值,执行后a里面保存的是b原来的值也就是相当于没有变
a ^= a;  //a = 0;
所以不是值相等有问题,而是两个变量的地址相同有问题