void swap(int *p1,int *p2){
*p1 = p1^p2;
*p2 = p1^p2;
*p1 = p1^p2;
}
這是在 [我是蔡金龍](http://www.reibang.com/users/e36540d0451c) 的文章 *[C語言的位操作(One)](http://www.reibang.com/p/73da7e180795) *里關(guān)于無參運算的一個例子救巷,這一個函數(shù)的特點是在沒有引入臨時變量(temporary variable)的前提下對兩個變量的內(nèi)容進行交換群叶。
而這是怎么做到的呢?以下是對這個函數(shù)的注釋
void swap(int *p1,int *p2){ // 假設(shè) p1 的補碼為 1011赁还,p2 為 0001
*p1 = *p1 ^ *p2; // 此時 *p1 為 1010 (1011 ^ 0001 == 1010)
*p2 = *p1 ^ *p2; // 此時 *p2 為 1011 (1010 ^ 0001 == 1011)
*p1 = *p1 ^ *p2; // 此時 *p1 為 0001 (1010 ^ 1011 == 0001)
}
觀察注釋后就會發(fā)現(xiàn),當 \*p1 和 \*p2 這兩個參數(shù)進行位間的異或運算(^)時廊宪,會得出一個很有趣的結(jié)果(在這個例子中是 1010)摹闽,這個結(jié)果與原參數(shù)(\*p1,\*p2)構(gòu)成一個互異關(guān)系(這個詞是自創(chuàng)的)泽示。換句話來說,對著三個參數(shù)中的任意兩個參數(shù)進行位間的異或運算蜜氨,都能夠得到余下的第三個參數(shù)械筛。因此,在同一時間里飒炎,只需要“記住”其中的兩個參數(shù)埋哟,就可以保證信息的完整性,從而不需要第三變量的引入郎汪。
--------------------
想到這個過程用圖像來表示可能會更直觀一些赤赊,于是就做了一個維恩圖(Venn diagram)的表示。
注意其中的 \*pt 其實就是運行函數(shù)中第一行之后的 \*p1煞赢,而位異或運算(a ^ b)在韋恩圖里可以表示為 ~(a ^ b) 【此 ^ 非彼 ^】
PS. 在制圖時犯了一個嚴重的錯誤抛计,在圖中的全集應(yīng)當是 \*p1 和 \*p2的交集 (\*p1 U \*p2 == U),所以**請無視圓和長方形之間區(qū)域**
![](http://upload-images.jianshu.io/upload_images/2157068-3a18d015b2ad2717.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
(原來的那篇因為沒有用 markdown照筑,結(jié)果弄不了 code block吹截。于是就刪掉然后用 markdown 再發(fā)了一遍,Orz)