Thinkers'Studio
JavaとC言語の自習ツール
マクロは機械的に置換するので注意

#define は記号定数やマクロの定義に用います

 記号定数は、一定の文字列に名前を与えておき、プログラムではその名前を記述するものです。
 マクロ定義は、引数を持つ記号定数であり、引数に指定された文字列を使って展開されます。 マクロ定義は、プログラムを読みやすくしたり、後から変更をしやすくするのに用いられます。

 今回は、マクロ定義の注意点です。次の例を見てください。
  (よくない定義例)    #define SQUARE(a)  a * a
 パラメータ a の二乗の値を求めるマクロですが、この書き方では次のようなケースで問題が起こります。
  (正しく動作しない例)SQUARE(2+3)  --> 2+3 * 2+3 と置換される
 演算子の優先度により 3 * 2 が先に計算され、11 になってしまいます。 次のように書くべきです。
  (正しい定義例)      #define SQUARE(a)  ((a) * (a))
 外側のカッコが必要な理由は、下のクイズにヒントがあります。

 マクロは機械的に置換するだけなので、パラメタが式の場合でも問題がないように、適切にカッコをつけて書かなければなりません。 次のクイズで実験し、確かめましょう。

(今回のクイズです)
 次のプログラムでは、ADD(加算)、SUB(減算)、MUL(乗算)、DIV(除算)の4つのマクロを定義しています。2つのパラメタを渡すと、それらの加減乗除の結果を返します。

#include <stdio.h>

#define ADD(a,b)   a + b
#define SUB(a,b)   (a) - (b)
#define MUL(a,b)   (a * b)
#define DIV(a,b)   ((a) / (b))

main()
{
    printf( "ADD:%d\n", ADD(4,2)/2 );
    printf( "SUB:%d\n", SUB(4,2)*5 );
    printf( "MUL:%d\n", MUL(4-2,2) );
    printf( "DIV:%d\n", DIV(4-2,2) );
}
 右側の式を見ると、( ) の付け方がすべて違います。 正しくカッコをつけて定義されているのは、どのマクロでしょう?
 どのように置換されるかトレースしながら、実行結果も予想してください。
   (答えは、次回のC言語の Tips で ・・・)

[ 関連記事 ] 変数の値を表示する便利なマクロ

前回のクイズの答え: (2)が正しい (前回の問題を見る

(1) は、int を返す strcmp の戻り値を if( strcmp( buf1, buf2 ) ) と真偽判定しています。strcmp は2つの文字列が等しいときに 0 を戻すので、判定が逆転してしまいます。
(3) は、文字列の内容の比較処理ではないので間違いです。 if( buf1 == buf2 ) は、「buf1 のアドレスと buf2 のアドレスは同じか?」という意味になります。なお、配列の名前だけを書くと配列の先頭要素のアドレスを意味します。