不使用中间变量交换两个数字

给定两个数字a和b,要求不使用中间变量交换二者

一般做法

一般的做法很简单

void swap(int &a;int &b){
int temp = a;
a = b;
b = temp;
}

不使用中间变量的做法

采用位操作符中的异或操作^

操作符 功能 用法
~ 取反 0变1,1变0
<< 左移 后面补0
>> 右移 前面补0,后面吞位
& 位与 只有两个都为1,则为1。x&…00100…用于提取x某一位
^ 位异或 只有一个为1,则为 1。用于判断两位是否相同 a^b^a = b 用于交换数值
\ 位或 有一个或2个1,则为1。用于做and运算

容易发现^的性质:

  1. 两个相同的数字做^操作得0
  2. 任何数字跟0做^操作还是它本身

所以可以通过下面的方式交换两个数字

void swap(int &a;int &b){
a = a^b;
b = b^a;
a = a^b;
}

这个程序大部分时间正确,但是有个致命缺陷,当a和b指向同一个位置时,计算a^b得0,也就是说a和b所指向的地址是同一个,所以此时a=b=0。所以上面这样写的前提是假设两个指针不会指向同一个位置。这也是编译器优化时经常考虑的一点,这种两个指针指向同一个存储器的情况叫做存储器别名使用(memory aliasing)。

因此正确的程序应该如下:

void swap(int &a;int &b){
if (a!=b){
a = a^b;
b = b^a;
a = a^b;
}
}