这里说的不使用临时变量不仅仅包括一个普通的内存变量,还包括外存能能够保存信息的媒介。也就是说,你手上只有这两个变量待交换的变量可以用来保存信息。
咋看起来似乎不可能,不使用第三方变量怎么可能交换两个变量的值呢?其实这是可以实现的,过程极其诡异(当然如果你自己想到的话那就不诡异了),仅仅用到一种运算,三行代码。
这是我们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;}
F-22's Trace
greensea 的个人主页
sky-city
极夜奁
小樱之町
拍!
偶跟你说了的
貌似如果字符串怎么办
交换指针呗
int strswp(char* a, char* b){
SWAP(a, b);
return 0;
}
#define SWAP(A, B) {A ^= B; B ^= A; A ^= B;}
这个有点小问题
一般可以加个if(A!=B)
至少你得保证&A!=&B
否则会囧
拍乃个头,才把偶的评论显示出来,不拍你拍谁
因为最近才进去后台才发现有待审留言
要怪就怪广告机器人去吧
拍!
拍乃个头
随便发了封邮件然后发现其中有 垃圾邮件 推广 字样,不知道是否会被过滤掉 的说
灭有
可见谷歌邮件的过滤很好很强大
话说还是看不懂……
看来在应试教育下还素有人比较会实践的嘛
应试对于搞科研的人来说还不算太有害
至少让咱科学工作者有良好的理论基础
不过其课程安排还是太慢了
其实高中就可以学微积分了嘛,真是的
a + b当a、b都比较大的话就会溢出~
^就没这个问题~
初次见面请多指教,V~
$a = $a + $b;
$b = $a – $b;
$a = $a – $b;