利用異或方式交換兩個變數值的原理是什麼?
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+bb=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++ 程序庫有哪些,為什麼?