2013-08-26 73 views
3

如果我定義了一個數字的絕對值作爲如何評估此聲明?

#define ABS(X) X >= 0 ? X : (-1) * X 

會有什麼

ABS(2) + ABS(-3) 

評估爲?我的朋友聲稱其評估爲2.

+3

你爲什麼不試試並找出答案? –

+0

那麼我也想知道爲什麼。 – Jessica

+0

'2> = 0? 2:(-1)* 2 + -3> = 0? -3:(-1)* -3' – dyp

回答

9

如果鍵入:

ABS(2) + ABS(-3) 

這將取代出來:

2 >= 0 ? 2 : (-1) * 2 + -3 >= 0 ? -3 : (-1) * -3 

可以打破下來:

2 >= 0 ? 2 : -5 >= 0 ? -3 : (-1) * -3 

或者:

2 >= 0 ? 2 : (-5 >= 0 ? -3 : (-1) * -3) 

第一部分(2 >= 0)的計算結果爲true,因此計算結果爲2

需要注意的是,你可以很容易地通過編寫宏爲解決這個問題:

#define ABS(X) ((X) >= 0 ? (X) : (-1) * (X)) 

這將使評估順序符合市場預期,並導致其解析爲5,而不是2,話雖這麼說,使用內聯函數會更乾淨,並避免整個場景。

+2

通過將它包裝在parens中,您對宏的修復不適用於所有情況。考慮'ABS(t> = 0?-1:1)'。這不會像人類預期的那樣擴大。對於宏,通常將參數包裝在parens中,幷包裝整個宏:'#define ABS(X)((X)> = 0?(X):(-1)*(X))' t處理所有的情況,尤其是X有副作用的情況下,但它確實相當好) – abelenky

+1

@abelenky True - 在括號內包裹內部'X'以嘗試在我的答案中處理這個問題。好點子。 –

5

預處理器執行基於文本(實際上是基於標記的)替換。它不關注邏輯表達式分組。

鑑於

#define ABS(X) X >= 0 ? X : (-1) * X 

ABS(2) 

擴展到

2 >= 0 ? 2 : (-1) * 2 

ABS(-3) 

擴展到

-3 >= 0 ? -3 : (-1) * -3 

所以

ABS(2) + ABS(-3) 

擴展到

2 >= 0 ? 2 : (-1) * 2 + -3 >= 0 ? -3 : (-1) * -3 

現在看運營商的分組方式,你就會明白爲什麼5直觀的答案是不正確的。

3

我是這樣看的:

ABS(2) + ABS(-3) 

變爲:

2 >= 0 ? 2 : (-1) * 2 + -3 >= 0 ? -3 : (-1) * -3 

添加一些括號澄清:

(2 >= 0) ? 2 : (((-1) * 2 + -3 >= 0) ? -3 : (-1) * -3) 

和評估:
2其實> = 0,因此:
(以及其他所有內容,從(((-1開始,將被忽略)

所以,我同意你的朋友。

+0

這是C預處理器;你*不能*假設不在那裏的人。 CPP執行純文本替換。 – michaelb958

+1

我沒有做任何關於parens的假設。我按照正常的操作順序放置它們,只是爲了幫助人們理解。如果我妥善安置它們,它們根本不會改變電腦解釋。 – abelenky

+1

這會教我盲目地曲解東西......我只是假設你正在衝入並重新強制要求5的「正確」結果。對不起。 – michaelb958