8.1 マクロ

オブジェクト形式マクロ

オブジェクト形式マクロとしての #define は、次のような形式で記述します。

#define マクロ名 置換後の文字の並び

強制されているわけではありませんが、一般的にマクロ名は大文字で表記することが多いです。また、置換後の文字の並びは空にしても構いません

コンパイルを行う直前で、ソースコード上の文字を置換し、その結果をコンパイルするのです。そうすることで、ソースコードの見た目を読みやすいまま保ちつつ、高度な処理を実現できます。

関数形式マクロ

関数形式マクロは、使用時の記述が関数を呼び出しているように見えるため、このように呼ばれます。関数形式マクロの定義は、次のように行います。

#define マクロ名(仮引数のリスト) 置換後の文字の並び

マクロ名の直後に ( ) で仮引数を指定する点が、オブジェクト形式マクロとの違いです。ただし、仮引数に型の指定はありません。仮引数がない場合は void とは書かず、単に ( ) の中を空にします。

通常の関数と異なり、マクロの場合はプリプロセスの段階で置換済みであることを忘れないようにしましょう。関数を呼び出すという行為そのものにも処理時間がかかるのですが、マクロの場合はこの呼び出し自体が発生しませんから、処理効率は向上します。

一方で、マクロを使っている箇所が個別に置換されるため、使用箇所が多いと、プログラムの大きさは増大しやすくなります。

なお、関数のように使うため、置換後の結果を複数行に渡って記述できた方が、見た目の上でも分かりやすくなることがあります。しかし、マクロの置換結果の中で普通に改行を行うことはできません。マクロの置換結果の中で改行を行うには、行末に \ を置きます。

#define INITIALIZE(a,b,c)  \
    (a) = 0; \
    (b) = 0; \
    (c) = 0;

特に、\ の後ろには改行しかあってはならないことに注意してください。

演習

演習 8-1

二つの値xとyの差を求める関数形式マクロを定義せよ。
diff (x, y)

演習 8-2

二つの値xとyの大きいほうの値を求める関数形式マクロは次のように定義できる。
#define max (x, y) (((x) > (y)) ? (x) : (y))
このマクロを利用して、四つの値a, b c d の最大値を求める、 次に示す各式がどのように展開さ
れるかを示し、考察を加えよ。
max (max (a, b), max(c,d))
max (max (max (a, b), c), d)

演習 8-3

type 型の二つの値を交換する、 関数形式マクロを次の形式で定義せよ。
swap (type, a, b)
たとえば、 int 型の変数xとyの値が5と10であるときに、 swap (int, x, y) を呼び出した後は、
xとyには10と5が格納されていなければならない。