2010-10-03 99 views
0

可能重複:
Potential Problem in 「Swapping values of two variables without using a third variable」這個技巧總是有效嗎?

我最近在一個社區,我們可以很容易地交換兩個號碼,而無需使用第三方使用XOR招讀取。

m^= n^= m^= n;提到了詭計。

你們認爲什麼?這個技巧總是有用嗎?

+2

不,它沒有。在這裏你去:http://stackoverflow.com/questions/3741440/potential-problem-in-swapping-values-of-two-variables-without-using-a-third-vari/3741450 – codaddict 2010-10-03 08:22:16

回答

0

它往往更危險(在你的情況下,它實際上是未定義的行爲;再加上如果一個數字爲零,事情就會出錯)。除非你的內存不足,否則最好只使用一個臨時變量(或stl swap函數)。這更清楚你正在做什麼,更容易維護。

5

你寫它的方式,它是未定義的行爲。這是因爲您在同一個序列點中多次修改變量。但是,如果你改寫它如下:

m ^= n; 
n ^= m; 
m ^= n; 

那麼它是安全的。然而,「有用」是另一個問題,它很少「有用」,有時它實際上比使用臨時實際更慢!

此外,您還需要注意別名(指針/引用),因爲如果您嘗試與自己交換某些內容,那麼最終會意外地將您的值歸零。例如:

#define SWAP(m, n) { m ^= n; n ^= m; m ^= n; } 

int x[] = { 1, 2, 3, 4 }; 
int i = 0; 
int j = 0; 
SWAP(x[i], x[j]); // whoops, x[0] == 0 now, not 1! 

更傳統的swap實現沒有這個問題。

3

不,它在C和C++中都是未定義的行爲。它有時可能有效,但你不應該依賴它。

而且即使是「固定」的變化並不總是工作:

m ^= n; 
n ^= m; 
m ^= n; 

此,如果m和n相同的變量引用失敗。在這種情況下,它將該值設置爲零。

C沒有引用,但即使使用C仍存在潛伏的危險,如果您嘗試使用這種伎倆:

  • 您可以嘗試把「工作」版本到宏SWAP,但如果使用SWAP(x,x)進行調用,則可能會失敗,並將x始終設置爲零。
  • 您可以嘗試的伎倆延伸到陣列中的交換兩個值,但如果再次使用相同的索引這可能失敗:

    a[m] ^= a[n]; 
    a[n] ^= a[m]; 
    a[m] ^= a[n]; 
    

現在如果M ==ñ再次值的[m]被設置爲零。

請不要使用這樣的「聰明」技巧。使用臨時變量交換兩個值。

1

有了這個技巧,你可以保存一個額外的內存位置來保存一個臨時值。 它可能對整數有效,但它是可讀的嗎?您的上一代優化器可能也會這樣做。

+0

現代CPU的做得更好臨時。他們可以並行執行這兩個任務,但他們必須停止XOR版本。 – GManNickG 2010-10-03 08:47:02

+0

@GMan:你的意思是指導配對?但在這種情況下可以配對哪些作業? – 2010-10-03 09:05:06

+0

@Nick:With'int temp = x; x = y; y = temp;',後兩者。 – GManNickG 2010-10-03 09:20:42