筆記一 2 1 8異或交換產生的問題

2021-07-22 08:58:09 字數 1054 閱讀 5517

部落格一放,又是好久沒有寫了。。。。

前兩天買了兩本磚頭書回來。一本是《深入理解計算機系統》第二版的的中文版,另一本便是《演算法導論》第三版的中文版。打算花時間認認真真消化完這兩本書。再結合自己幾年的工作經驗,根據理論,做一些分析,力爭找到問題的本源,以及解決辦法,多寫幾句沒事,爭取把問題講透。另外一點,便是想把不紮實的知識點,通過閱讀這本書,把東西吃透。需要整理的**,自己扔在csdn的git託管中。今天分析的這個**的原始檔是2.1.8-swap.c,可以參考一下。

今天主要是看到書的2.1.8節,c語言的位運算中。聊到了用異或實現a和b資料交換的問題。實際上這個函式在實際應用上,並沒有多少價值,但最主要的是加深原理性的理解。

void swap(int

*x, int

*y)

說實話,單看這段**,也不會出現問題。我原來印象出,一直覺得是溢位會產生的問題。但是自己寫**驗證過,溢位並沒有產生問題。讀了文章中,才反應過來這個函式真的會出現問題。但是如果不是看到練習題2-11,我真的還想不到哪兒出了問題。。。。

異或交換的依據是a^b^a = b,然後有乙個加法逆元的結論,a^a= 0。我聯想起來,用加減去做swap的乙個例子。

void swap2(int

*x, int

*y)

實現原理也跟加法逆元的概念有關。a+b-a = b,同異或a-a = 0 那麼,如果不用第三個數,做資料交換,只要他有加法逆元,即這個數與它本身的運算,結果為0。就可以用做資料交換來使用。

看到還有一句話的實現

a = b+a - ( b=a );
實際上也是用了加法逆元的特性,寫法不一樣,原理是一樣的。

也是正因為這乙個特性,導致陣列逆序時,產生了問題。在逆序的陣列為奇數時,最後變成了自己交換。然後a^a=0的***這時候就顯現出來了。a-a=0的***也同樣。。。

書中的要求修改的**,我也改過,仍然放在2.1.8-swap.c這個檔案中,可以做參考。規避掉奇數個的陣列逆序時產生的問題。

這個問題就分析到這裡,後面力爭在每乙個問題上,都挖出源頭。

異或操作交換元素容易產生的問題

利用異或操作交換兩個元素已不是什麼新鮮話題了。1異或寫法 2傳統寫法 有很多程式設計師已經逐漸接受並喜歡使用這種異或寫法了,問之優點,大多數程式設計師都會從時間效能,空間效能,簡潔性三方面做回答。由於位操作較賦值操作的確快了些,空間上僅僅節約乙個單位,至於簡潔性就有點牽強了 明顯差不多嘛 可讀性反倒...

交換的異或實現

如果想交換 a 和 b 的值,我們通常的做法是 宣告乙個臨時變數 temp,然後再實現互換,這種方式常見的讓我幾乎認為 就應該這樣做,但今日拜讀 深入理解計算機系統 一書時,卻發現了另一種巧妙的實現方式,不用第三個位置來臨時儲存,只需位操作 異或 即可。定義 a b a b ab a 為非a 1 1...

通過異或交換變數的數值

通過異或交換變數的數值,最我最為推薦的swap方法,相比 借用第三變數,temp a a b b temp 異或交換 更有效率!利用加減法,a a b b a b a a b 異或交換 適用範圍更廣。這裡的適用範圍更廣,說得有點牽強。加減法給我的直觀感覺是 不安全,當 a a b 的結果超出了該變數...