交换两个变量值的操作估计是程序设计里面非常常见也被大家认为最简单的一项操作了。如果我们要交换想两个变量x,y的值,大多数人会想到创建一个临时变量z,然后通过
z=x; //step 1
x=y; //step 2
y=z; //step 3
这样的简单3步,交换就搞定了。不过我们还可以通过位操作来实现这个交换过程,而且根本不会用到第3个临时变量。例如下面的程序:
#include <iostream>
using namespace std;
void swap(int *x,int *y)
{
*x = *x ^ *y; //step 1
*y = *x ^ *y; //step 2
*x = *x ^ *y; //step 3
}
int main()
{
int a=1;
int b=5;
cout<<"a="<<a<<" ; "<<"b="<<b<<endl;
swap(&a,&b);
cout<<"a="<<a<<" ; "<<"b="<<b<<endl;
return 1;
}
初看起来觉得不可思议,不过自己运行一下就知道,a,b的值确实是交换了。
为什么通过step1,step2,step3那3个看似奇怪的操作就能把值给交换了呢?让我们分析一下:
简单介绍一下^(异或)操作:两值不同,结果为一,否则为0。即0^0=0,1^1=0,0^1=1,1^0=1
推广一下,有一数a,则有0^a=a, 1^a=~a,a^a=a, 0不会使a的每位发生变化,1使a的每位都取反, a与a每位都相同,异或结果每位都是0,结果也就是0了。
知道了上面的就好办了,我们看看程序中的操作
step 1:*x = *x ^ *y;
step 2:*y = *x ^ *y;
结合前2步,在step2中 *y = *x ^ *y ^ *y = *x ^ (*y ^ *y) = *x ^ 0 = *x
step 3:*x = *x ^ *y;
结合前3步,在step3中 *x = *x ^ *y ^ *x = *y ^ (*x ^ *x) = *y ^ 0 = *y
看看,上面有了*y = *x 和 *x = *y ,巧妙的3步操作使这两个值真的交换了。它利用了
a ^ b ^ b = a
a ^ a ^ b = b
我们注意到上面2个式子中都有a ^ b ,即我们可以先把
a ^ b的结果存储在任意一个变量中,然后我们还可以通过^a或者^b的操作把b或者a还原出来,这就是节省第3个变量的秘密。