利用異或方式交換兩個變數值的原理是什麼?

a=a^b;

b=a^b;

a=a^b;


首先需要知道關於異或運算的一些性質:

  • 異或滿足交換律和結合律
  • x ^ x == 0
  • x ^ 0 == x

然後稍微列一個表就很清楚了(表中黑框部分的a和b代表的是a和b的初始值):

所以這樣做能夠交換兩個變數。

---------------- 以下為私貨時間 ----------------

不建議在實際使用中採用這樣的寫法。這種奇技淫巧雖然看起來十分巧妙,但這樣並不見得能夠比樸素的交換來的更快。而且這種方法存在一個缺陷:如果 a 和 b 引用的是同一個變數的話,使用這種方法會使得這個變數變為0。


如果我說這是一種「信道極化」(對,就是那個5G短碼信令標準的極化碼的技術原理) 的信道合併分離的方法(這裡是個無噪信道),不會有人說我裝逼吧。


在加法群裡面,

記a的逆為a",

那麼交換a,b可以寫成

a=a+b

b=a+b"

a=a+b"

如果是實數加法群,a"就是-a

如果是實數乘法群,a"就是1/a

如果是整數亦或群,a"還是a,逆元是本身,寫起來就很有意思了。


a^b=diff (diff為a,b的差異)

a^diff=b (a減去[a,b的差異diff]等於b)

b^diff=a (b減去[a,b的差異diff]等於a)


因為異或是位運算,利用異或方式交換變數其實就是交換兩個變數對應的位。所以只要研究會1bit大小的變數交換的原理就好了。而研究1bit大小變數交換原理的方法就是窮舉了。

+------+--+--+--+--+
|ab的值|00|01|10|11|
+------+--+--+--+--+
|a=a^b |00|11|10|01|
+------+--+--+--+--+
|b=a^b |00|10|11|01|
+------+--+--+--+--+
|a=a^b |00|10|01|11|
+------+--+--+--+--+

+--+--+--+--+
從 |00|01|10|11|
+--+--+--+--+
到 |00|10|01|11|
+--+--+--+--+

實現了位的交換 。

兩個變數對應的位交換了,兩個變數也就交換了。

至於兩個變數為同一引用時會出現什麼結果,照著上面的方法自己試一試就知道了。


原理上面都回答了.我就不重複了.說說問題吧.

1.如果你用這個辦法交換2個指針的內容.那麼你要先檢查2個指針指向的地址是否相同.不然會導致內容被清0

2.速度並不比樸素的中間變數交換快.

結論.別這麼干.


原理當然就是異或的原理或者說特性了。

異或,英文xor,中文可以理解成兩個數不一樣(「異」)的話就進行「或」操作,其他情況均為0。

異或1可以轉置,異或0不變,這是cpp書中所說最簡單的也是最基本的應用。

異或交換兩個值,實質就是兩點:

相同的兩個數異或為0,

然後任何數異或0都不變。


推薦閱讀:

為什麼計算機里加上存儲功能可以代替改變電路?
為什麼開源軟體絕大部分都是C語言寫的,而商業軟體大多數是C++開發的?
成為一個優秀的程序員,一定要精通C/C++嗎?
如今存在用機器語言編寫出的程序么?
你工作中最推薦的 C/C++ 程序庫有哪些,為什麼?

TAG:演算法 | C編程語言 | C | CC |