2014-12-27 85 views
3

在Python,可以容易地與像這樣的表達式交換2個變量的值:魔術在C++與此表達式x = Y X +(Y = X)

x, y = y, x 

在C++中,在另一方面,如果你想交換2個變量的值,您通常使用一個臨時變量來存儲您的變量之一的值,這樣的事情:

int var1 = 100; 
int var2 = 200; 

int temp = var1; 
var1 = var2; 
var2 = temp; 

這是很容易的,但你必須寫很多代碼。

,我一直在關注他關於C++講座教授發現了交流的一個新的緊湊型方式2個變量的值在一個神奇的方式:

int x = 200; 
int y = 100; 

x = y - x + (y = x); 

這似乎令人難以置信,但它的工作原理都與他使用的編譯器和我的Apple LLVM version 6.0 (clang-600.0.56)

似乎表達被解釋方式如下:

  1. (Y = X)//返回
  2. -x + x = 0的
  3. x的x中的值= Y + 0
  4. X = Y
  5. Y = X //最後,Y接收x的初始值

如果我試圖交換在一個循環的一些變量的值,這似乎也工作:

for (int i = -10; i <= 10; i++) { 
    for (int j = 10; j >= -10; j--) { 
     int x = i, y = j; 
     x = y - x + (y = x); 

     std::cout << "x = " << x << "\ny = " << y << '\n'; 
    } 
} 

我們已經看到,交換完成,但我的編譯器給了我這樣的警告:

main.cpp中:28:22:警告:未測序修改和訪問爲 'Y' [-Wunsequenced]

如果有一個警報,I S這不是一種交換2個變量值的新標準方式,而只是這位教授的一個巧妙的解決方法。

爲什麼這種方法在C++中沒有標準化,爲什麼它的工作原理?

+1

提示:http://en.wikipedia.org/wiki/Sequence_point –

+9

std :: swap()也是consise – stefaanv

回答

9

這是未定義的行爲,它不能保證工作。沒有指定表達式中參數的評估順序。因此,在執行y = x分配之前或之後,允許訪問y的減法值。

這樣指定的原因是允許優化的靈活性。

6

它「有效」,因爲你運氣不好。

是的,我說不幸。代碼具有未定義的行爲;它似乎「工作」的事實意味着你的編譯器讓你擺脫了下次運行時可能失敗的代碼。

x = y - x + (y = x); 

目的y被訪問兩次,一次讀取它的值,並且一旦爲一個值分配給它。該語言沒有定義這些訪問的發生順序 - 或者按照任何順序發生。正如警告信息所述,他們「不確定」。可能的行爲不僅限於這兩種可能的順序;行爲完全未定義。

此外,加法和/或減法可能會溢出,這是未定義行爲的另一個潛在來源。

+3

它沒有錯誤診斷問題。它打印了一條警告。 – Barmar

+0

@Barmar:好點,我已經相應地更新了我的答案。 –

2

此,'X = Y - X +(Y = X);,在C未定義行爲 - 由C99規範中列出的一個未定義的行爲是:

兩人之間序列點,其目的在於改性一次以上,或 被修改並且在現有值被讀以外,以確定 值存儲

唯一序列點在該表達式是表達式的開始和完成的結束表達。

+0

是的,但問題是標記爲C++。 :d –

相關問題