在不使用临时变量的情况下交换两个变量的值

这里说的不使用临时变量不仅仅包括一个普通的内存变量,还包括外存能能够保存信息的媒介。也就是说,你手上只有这两个变量待交换的变量可以用来保存信息。
咋看起来似乎不可能,不使用第三方变量怎么可能交换两个变量的值呢?其实这是可以实现的,过程极其诡异(当然如果你自己想到的话那就不诡异了),仅仅用到一种运算,三行代码。
这是我们C语言老师留给我们的一道问题,不算作业,仅供课后自行思考。偶听到这题目的时候虽然还没有觉得这不可能,但一下子还真的想不出来应该怎么做。不过后好像是在研究某个东西的时候得到启发,想到了这个办法。
下面开始,我们仅仅用到异或运算,异或运算符这里用 ^ 代替。
三行代码,假设两个变量是a和b

a = a ^ b
b = a ^ b
a = a ^ b

完成,现在a和b的值已经交换了
是不是很不可思议?其实知道原理以后就一点也不诡异了。下面解释原理

异或操作就不多说了,相同为0相异为1
算了还是说清楚一点,可能真的有人不知道(我敢保证我们班上就会有不少人不知道)
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
异或运算是符合交换律以及结合律的,这里不证明了(其实偶也没想过怎么证明)
显然,相同的数异或结果为0,而一个数与0异或的结果还是这个数本身(你看,1异或0还是1,0异或0还是0),由此可以知道
x ^ x = 0
y ^ y = 0
0 ^ x = x
0 ^ y = y
下面,将x和y套入上面的方法,每一步过后x和y的值如下
x    y
x = x ^ y    x^y    y
y = x ^ y    x^y    (x^y)^y
x = x ^ y    (x^y)^((x^y)^y)    (x^y)^y

接下来把结果化简
第二步完成之后的y:
(x^y)^y=x^(y^y)=x^0=x;可以看到,第二步完成以后y的值已经变成了x的值
第三步:化简x的结果(蓝色字体是利用第二步的结果):
(x^y)^((x^y)^y)=(x^y)^x=x^x^y=0^y=y;好了,这下x也变成y了
就这么简单,x和y交换完成,一点都不诡异

———–2009年8月28日更新————
浏览以前的日志时发现上面那三行异或代码很好看,然后试试用C的语法写下来,应该会更简洁美丽

a ^= b;
b ^= a;
a ^= b;

做成宏

#define SWAP(A, B) {A ^= B; B ^= A; A ^= B;}
This entry was posted in 零零散散 and tagged , . Bookmark the permalink.

15 thoughts on “在不使用临时变量的情况下交换两个变量的值

  1. #define SWAP(A, B) {A ^= B; B ^= A; A ^= B;}  

    这个有点小问题
    一般可以加个if(A!=B)
    至少你得保证&A!=&B
    否则会囧

    • 应试对于搞科研的人来说还不算太有害
      至少让咱科学工作者有良好的理论基础
      不过其课程安排还是太慢了
      其实高中就可以学微积分了嘛,真是的

发表评论

电子邮件地址不会被公开。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>