数値の絶対値を次のように定義した場合
#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))
これにより、評価順序が期待どおりに維持され、2 ではなく 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 という直感的な答えが正しくない理由がわかります。
これが私がそれを読む方法です:
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 なので: 2
(そして で始まる他のすべて(((-1
は無視されます)
だから、私はあなたの友人に同意します。