マクロを定義するとしましょう:
#define MAX(x,y) ((x)>(y)?(x):(y))
に電話するとどうなりますMAX(I++,J++)
か?
なぜ答えが期待どおりにならないのか理解できませんでした。
マクロはプリプロセッサ専用です。これは、C コンパイラによってコンパイルされるものです。
(((I++)>(J++))? ((I++):(J++)))
ご覧のとおり、I が J より大きい場合、I は 2 回インクリメントされ、J は 1 回インクリメントされます。それ以外の場合はその逆です。
あなたのマクロは正しくありません。ここでは括弧の外側の層が間違っているため、コンパイル エラーが発生します。
((I++):(J++))
MAX(I++,J++)
に展開し(((I++)>(J++))? ((I++):(J++)))
ます。I++
とが 2 回出現することに注意してくださいJ++
。したがって、これらは両方とも比較後にインクリメントされ、結果のいずれかが再びインクリメントされます。
代わりにインライン関数を使用できます。
inline int MAX(int x, int y)
{
return x > y ? x : y;
}
しかし、マクロには、どの型でも機能するという利点があると思います。
int res = MAX(x,y);
マクロでは
(((x) > (y)) ? (x):(y));
今ならx = a++
、y = b++
それは次のように翻訳されます
(((a++) > (b++)) ? (res = a++):(res = b++));
したがって、条件が真であるパスの場合、どちらの変数でも合計で 2 回インクリメントされますが、格納される結果の値res
は 1 つのインクリメントしかありません (ポスト インクリメントを使用しているため)。
関数/マクロ呼び出しで post-inc を使用すると、微妙なロジックの不具合が発生する可能性があるため、注意が必要です。
変数を関数/マクロにそのまま渡すことを好み、それに対する変更を個別に行うと、そのような問題で時間を節約できます。