零.Introduction
利用異或操作交換兩個元素已不是什麼新鮮話題了。
1異或寫法:
{ a ^= b; b ^= a; a ^= b;}
2傳統寫法:
{ int temp = a; a = b; b = temp;}
有很多程式員已經逐漸接受並喜歡使用這種異或寫法了,問之優點,大多數程式員都會從時間效能,空間效能,簡潔性三方面做回答。由於位操作較賦值操作的確快了些,空間上僅僅節約一個單位,至於簡潔性就有點牽強了(明顯差不多嘛),可讀性反倒降低了,我覺得大多數程式員採用異或寫法有部分因素是因為覺得這種寫法比較酷。但為了這點酷,我們可能要在正確性等方面投入很多精力,付出更多的代價。
一.類型適用性
傳統的賦值寫法可適用於多種類型,其正確性也是毋庸置疑的。而異或寫法除了整型之外,不敢保證其疑惑操作符在作用與浮點或自訂類型時還能正確的工作。如果不想證明的話,那就老老實實使用傳統寫法吧。
二.正確性
在使用中交換操作往往被提取成swap函數,按照兩種寫法分別如下:
1.異或寫法
void swap(int* a, int* b){ *a ^= *b; *b ^= *a; *a ^= *b;}
2.傳統寫法
void swap(int* a, int* b){ int t = *a; *a = *b; *b = t;}
實參調用往往是這樣swap(&num1, &num2);一般情況下兩種寫法都能正確工作。但是考慮如下情況:
int a = rand(); int* p1 = &a; int* p2 = &a; swap(p1, p2);
當兩個指標變數指向同一個地址的資料時,只有傳統寫法可以工作。
究其原因傳統寫法把地址上的值取了出來,而異或寫法直接在原地址上進行值運算,一次異或之後值就成了0,兩個指標都指向這個地址,後面再怎麼異或也只能是0了。可以畫個圖來試試。
在應用中,如果要使用異或寫法來交換元素,就得確保所傳兩個地址不一樣,否則就會出現這話總錯誤。
為了一點酷,一個單位空間的節省,極少的時間效能增益,可讀性降低了,正確性的風險更大了,操的心多了,試問,還有必要那麼寫嗎?