プリプロセッサー定義ディレクティブ は、これ以降のマクロ の出現を、指定された置換トークンに置き換えるようプリプロセッサーに指示 します。
#define COUNT 1000
int arry[COUNT];
int arry[1000];
#define MAX_COUNT COUNT + 100
プリプロセッサーは、MAX_COUNT のこれ以降の出現を COUNT + 100 で置き換えます。 次に、プリプロセッサーは、これを 1000 + 100 で置き換えます。
#define a 10
a.2
関数類似マクロは、オブジェクト類似マクロより複雑であって、その定義は、 仮パラメーターの名前をコンマで区切って、括弧で囲んで宣言します。 空の正式パラメーター・リストは有効です。そのようなマクロを使用して、引数を取らない関数をシミュレートすることができます。 C99 は、可変個の引数を持つ関数類似マクロのサポートを追加しました。
移植性のため、1 つのマクロに は、パラメーターが 31 を超えないようにする必要があります。パラメーター・リストは、仮パラメーターとして、省略符号 (…) で終了することができます。 この場合には、置換リストに ID __VA_ARGS__ を使用できます。
#define SUM(a,b,c) a + b + c
SUM(1,,3) /* No error message.
1 is substituted for a, 3 is substituted for c. */
#define debug(...) fprintf(stderr, __VA_ARGS__)
debug("flag"); /* Becomes fprintf(stderr, "flag"); */
#define SUM(a,b) (a + b)
c = SUM(x,y);
c = d * SUM(x,y);
c = (x + y);
c = d * (x + y);
#define SQR(c) ((c) * (c))
y = SQR(a + b);
y = ((a + b) * (a + b));
y = (a + b * a + b);
# 演算子および ## 演算子の引数は、 関数類似マクロのパラメーターの置換の前に 変換されます。
プリプロセッサー ID は、いったん定義されると定義されたままとなり、 言語のスコープ決定規則とは関係なく、有効となります。 マクロ定義のスコープは定義から始まり、 対応する #undef ディレクティブに遭遇するまで終了しません。対応する #undef ディレクティブがない場合、そのマクロ定義 のスコープは、変換単位の終わりまで続きます。
#define x(a,b) x(a+1,b+1) + 4
x(20,10)
x(20+1,10+1) + 4
マクロ x を、それ自体の中で繰り返し展開しようとするよりも、 上述の展開を行います。 マクロ x が展開された後で、そのマクロは、関数 x() の呼び出しとなります。
#define debug
2 番目のプリプロセッサー #define ディレクティブを用いて、 定義済みの ID またはマクロの定義を変更することができます。 ただし、2 番目のプリプロセッサー #define ディレクティブの前に、 プリプロセッサー #undef ディレクティブがある場合に限ります。#undef ディレクティブは、最初の定義を無効にして、 同じ ID を再定義で使用できるようにします。
プログラムのテキストの中については、プリプロセッサーはマクロ呼び出しのための 文字定数またはストリング定数のスキャンを行いません。
以下のプログラム例には、2 つのマクロ定義と、その定義されている両方のマクロを 参照するマクロ呼び出しが含まれています。
/**
** This example illustrates #define directives.
**/
#include <stdio.h>
#define SQR(s) ((s) * (s))
#define PRNT(a,b) ¥
printf("value 1 = %d¥n", a); ¥
printf("value 2 = %d¥n", b)
int main(void)
{
int x = 2;
int y = 3;
PRNT(SQR(x),y);
return(0);
}
プリプロセッサーによって解釈された後、このプログラムは、 以下のものに等価のコードによって置き換えられます。
#include <stdio.h>
int main(void)
{
int x = 2;
int y = 3;
printf("value 1 = %d¥n", ( (x) * (x) ) );
printf("value 2 = %d¥n", y);
return(0);
}
value 1 = 4
value 2 = 3
可変数引数マクロ (variadic macro) 拡張機能は、可変個の引数を持つマクロに関連した、C99 の 2 つの拡張機能です。これらの拡張の 1 つは、変数引数 ID を __VA_ARGS__ からユーザー定義の ID に名前変更するためのメカニズムです。 もう 1 つの拡張機能は、変数引数が指定されていない場合に、可変数引数マクロ内のダングリング・コンマを除去するための手段を提供します。 どちらの拡張機能も、GNU C を使用して開発された プログラムの移植を容易にするためにインプリメントされています。
#define debug1(format, ...) printf(format, ## __VA_ARGS__)
#define debug2(format, args ...) printf(format, ## args)
呼び出し | マクロ展開の結果 |
---|---|
debug1("Hello %s/n"."World"); | printf("Hello %s/n"."World"); |
debug2("Hello %s/n"."World"); | printf("Hello %s/n"."World"); |
プリプロセッサーは、関数マクロへの変数引数が省略されるかまたは空であり、関数マクロ定義内の変数引数 ID の前に ## を伴うコンマがある場合に、末尾のコンマを除去します。