如果我定義了一個數字的絕對值作爲如何評估此聲明?
#define ABS(X) X >= 0 ? X : (-1) * X
會有什麼
ABS(2) + ABS(-3)
評估爲?我的朋友聲稱其評估爲2.
如果我定義了一個數字的絕對值作爲如何評估此聲明?
#define ABS(X) X >= 0 ? X : (-1) * X
會有什麼
ABS(2) + ABS(-3)
評估爲?我的朋友聲稱其評估爲2.
如果鍵入:
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,話雖這麼說,使用內聯函數會更乾淨,並避免整個場景。
通過將它包裝在parens中,您對宏的修復不適用於所有情況。考慮'ABS(t> = 0?-1:1)'。這不會像人類預期的那樣擴大。對於宏,通常將參數包裝在parens中,幷包裝整個宏:'#define ABS(X)((X)> = 0?(X):(-1)*(X))' t處理所有的情況,尤其是X有副作用的情況下,但它確實相當好) – abelenky
@abelenky True - 在括號內包裹內部'X'以嘗試在我的答案中處理這個問題。好點子。 –
預處理器執行基於文本(實際上是基於標記的)替換。它不關注邏輯表達式分組。
鑑於
#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直觀的答案是不正確的。
我是這樣看的:
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
開始,將被忽略)
所以,我同意你的朋友。
這是C預處理器;你*不能*假設不在那裏的人。 CPP執行純文本替換。 – michaelb958
我沒有做任何關於parens的假設。我按照正常的操作順序放置它們,只是爲了幫助人們理解。如果我妥善安置它們,它們根本不會改變電腦解釋。 – abelenky
這會教我盲目地曲解東西......我只是假設你正在衝入並重新強制要求5的「正確」結果。對不起。 – michaelb958
你爲什麼不試試並找出答案? –
那麼我也想知道爲什麼。 – Jessica
'2> = 0? 2:(-1)* 2 + -3> = 0? -3:(-1)* -3' – dyp