2016-02-26 116 views
17
int x = 5,y = 10; 
bool boolean = 0; 
int k = (boolean ? ++x, ++y : --x, --y); 
cout<<k; 

當布爾值爲0時,它輸出9,但是當它是1時,它輸出10.我知道這是因爲優先級而發生的,但無法準確理解它是如何發生的,請幫我理解這一點。這個三元條件表達式是如何執行的?

注:我知道我能得到期望的輸出,如果我用括號,或者最好寫一個乾淨的代碼,我只是用這個來了解編譯器將根據優先評估這樣的表達式。

+0

最好使用布爾型的「true」和「false」 – Garf365

+4

閱讀_comma operator_和前綴遞增遞減。 –

+1

你會期望什麼輸出? –

回答

40

,?:優先級低。這意味着全parenthesising是:

int k = ((boolean ? (++x, ++y) : --x), --y); 

正如你所看到的,k總是初始化到--y值。只是如果booleantrue++y發生在此之前。


當尋找表達式的全括號形式,認爲它是構建表達樹(如最低優先級操作是在根目錄)。

查找表達式中的最低優先級操作,並parenthesise其左側參數和它的右手側的說法。在括號內的子表達式中遞歸地重複。

+0

謝謝,你的回答有幫助,你能告訴我給定優先順序的一個特定表達式的加括號的步驟,我不能決定哪些組加括號爲這樣的表達式。 –

+0

@KaranJoisher我試着相應地擴大了答案。 – Angew

+1

@KaranJoisher爲什麼不只是放在parens中以消除所有的不明確性:'int k =(boolean?(++ x,++ y):(--x, - y));'立即明確哪些部分去哪裏。沒有必要試圖找出運營商的優先順序。 –

22

由於具有最低operator precedence逗號操作符,你的發言實際上是等於

k = (boolean ? (++x, ++y) : --x), --y; 

這意味着,當booleantrue你既增加和減少y。在兩種情況下三元表達式的結果都被丟棄,k僅被分配--y的結果。

應當指出的是,這是不是不確定的行爲,如逗號運營商引入序列點。


爲了得到你所期望的結果,你需要做的

k = boolean ? (++x, ++y) : (--x, --y); 

注意嚴格不需要圍繞++x, ++y括號,但它確實使表達更加清晰。由於那麼代碼是在其意圖更可讀明確

if (boolean) { 
    ++x; 
    ++y; 
} else { 
    --x; 
    --y;  
} 
int k = y; 

+3

我想知道是否有人會談論代碼的非UBness。感謝那。 – NathanOliver

+1

@NathanOliver好吧,它*在這種情況下很重要。 :) –

+1

@NathanOliver你應該得到UB編寫這樣的代碼。我不是編譯器,我不想解析代碼。 – edmz

8

鑑於上述優異的答案,應該代替寫。這將幫助任何人誰擁有代碼的維護(包括原作者!),而不必提了問題或擔心的分配,?:還是什麼物流優先這樣一個複雜的表達式是浪費時間的人。任何現代編譯器都會優化這個和上面的代碼

+6

OP的帖子很巧妙地使用了排序,但也會導致你的同事恨你的「聰明」類型。 – MtRoad

+1

是的,好點,最後。 –

+0

落選者能否解釋原因?我是否錯過了一些至關重要的優化前機會,這些重要性我的代碼毫無意義?請給我一個很好的理由來寫一個初始化作爲OP的。或者不如我的。 –