マクロを定義するときは、基本的に、最初の例のような奇妙な動作を防ぐために、マクロ パラメーターを括弧に入れて、結果を括弧に入れて、副作用なしで安全に使用できるようにする必要があります。使用する
#define SQR(x) ((x)*(x))
は、数学的に正しいものにSQR(a+b)
展開されます ( ab+a+b に等しい とは異なります)。((a+b)*(a+b))
a+b*a+b
マクロの前後に何かを置いても、マクロには入りません。あなたの例ではそう++SQR(x)
なり++x*x
ます。
次の点に注意してください。
int a=3, b=1;
SQR(a+b) // ==> a+b*a+b = 3+1*3+1 = 7
++SQR(a+b) // ==> ++a+b*a+b ==> 4 + 1*4 + 1 = 9
// since preincrement will affect the value of a before it is read.
いずれかの時間、つまりインクリメントを読み取る++SQR(a+b)
前にプリインクリメントが開始され、その後 2 回使用されるため、結果が予想より 2 高くなるため、 2 ずつインクリメントしているように見えます。a
a
注@JonathanLeffler が指摘するように、後者の呼び出しは未定義の動作を呼び出します。評価が左から右に行われるとは限りません。異なるコンパイラ/OS では異なる結果が生成される可能性があるため、決して依存しないでください。