プログラミング言語 C
(前に説明したように マクロは) 引用符で囲まれた 文字列には 適用されない。
しかし 置き換える トークン列のパラメータ (←text) の直前に # が ついていれば、対応する引数が 文字列引用符 ( " ) で 囲まれる。
このとき 文字列中にある " または \ という 文字の前には (自動的に) \ 文字が 挿入される。(← 特殊文字として 認識されないように)
デバック用に 使われる 関数 printf() を、文字列と 組み合わせて プリントマクロとして 考えてみよう。
#define D_PRINT(expr) printf(#expr " = %g\n", expr)
引数に x/y を挿入して、
D_PRINT(x/y);
としたとき、このマクロは 次のように 展開される。
printf("x/y" " = %g\n", x/y);
(それぞれの 引用符で囲まれた) 文字列は 結合されるので、これは 下の文と 同じである。
printf("x/y = %g\n", x/y);
演算子 ## を 用いると、マクロの展開中に 実引数を 結びつけることができる。
define PASTE(front, back) front ## back
PASTE(name, 1);
として 展開すると、
text 中の 各パラメータ (← front と back) は 実引数 (← name と 1) に 置き換えられる。
また、## と その両側にある スペース部分は (自動的に) 除かれるので、結果として、
name1
という 文字記号が 得られることになる。
## を 用いる場合、実引数に カッコで囲まれた トークンが 入るときには、マクロを2つのレベルに 分ける 必要がある。
define CAT(x, y) x ## y
define X_CAT(x, y) CAT(x, y)X_CAT((1, 2), 3);
として 展開させると、X_CAT 自体には ## が 含まれないので、その結果、123
という 文字記号が 得られる。(p110-111, p289-291)
こんなかんじ、ですか ?
- /* love.c */
- #include
- #define LOVE(person) printf("I love %s.\n", #person)
- main()
- {
- LOVE(you);
- return 0;
- }
「叫ぶ ! C プログラマ」(isbn:4881663763) によれば、## は 実際には、こんなふうに 使用されるらしい。(p128)
- /* country.c */
- #include
- #define NUM_CO(number) printf("country : %s\n", country ## mumber)
- main()
- {
- char *country01 = "U.S.A.";
- char *country81 = "Japan";
- NUM_CO(81);
- return 0;
- }