無參運(yùn)算小記

void swap(int *p1,int *p2){
*p1 = p1^p2;
*p2 = p1^p2;
*p1 = p1^p2;
}


這是在 [我是蔡金龍](http://www.itdecent.cn/users/e36540d0451c) 的文章 *[C語言的位操作(One)](http://www.itdecent.cn/p/73da7e180795) *里關(guān)于無參運(yùn)算的一個例子,這一個函數(shù)的特點(diǎn)是在沒有引入臨時變量(temporary variable)的前提下對兩個變量的內(nèi)容進(jìn)行交換。

而這是怎么做到的呢?以下是對這個函數(shù)的注釋

void swap(int *p1,int *p2){ // 假設(shè) p1 的補(bǔ)碼為 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),當(dāng) \*p1 和 \*p2 這兩個參數(shù)進(jìn)行位間的異或運(yùn)算(^)時,會得出一個很有趣的結(jié)果(在這個例子中是 1010),這個結(jié)果與原參數(shù)(\*p1,\*p2)構(gòu)成一個互異關(guān)系(這個詞是自創(chuàng)的)。換句話來說,對著三個參數(shù)中的任意兩個參數(shù)進(jìn)行位間的異或運(yùn)算,都能夠得到余下的第三個參數(shù)。因此,在同一時間里,只需要“記住”其中的兩個參數(shù),就可以保證信息的完整性,從而不需要第三變量的引入。

--------------------

想到這個過程用圖像來表示可能會更直觀一些,于是就做了一個維恩圖(Venn diagram)的表示。

注意其中的 \*pt 其實(shí)就是運(yùn)行函數(shù)中第一行之后的 \*p1,而位異或運(yùn)算(a ^ b)在韋恩圖里可以表示為 ~(a ^ b) 【此 ^ 非彼 ^】

PS. 在制圖時犯了一個嚴(yán)重的錯誤,在圖中的全集應(yīng)當(dā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)

(原來的那篇因?yàn)闆]有用 markdown,結(jié)果弄不了 code block。于是就刪掉然后用 markdown 再發(fā)了一遍,Orz)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,740評論 18 399
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,199評論 1 10
  • (1) 房間里的劉磊窩在那個看上去有些年代的沙發(fā)上,整個房間昏昏暗暗的,窗戶被窗簾擋住了,什么都照不進(jìn)來。 劉磊看...
    F_先生閱讀 426評論 0 0
  • 【蝸牛計(jì)劃,每天進(jìn)步一點(diǎn)點(diǎn)】 我是清泉 打卡日期:2017年8月20日 打卡天數(shù):第51天 (1)我今年的三個年度...
    沈曼柔閱讀 554評論 0 0

友情鏈接更多精彩內(nèi)容