プログラミング言語 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)

こんなかんじ、ですか ?

  1. /* love.c */
  2. #include
  3. #define LOVE(person) printf("I love %s.\n", #person)
  4. main()
  5. {
  6. LOVE(you);
  7. return 0;
  8. }

「叫ぶ ! C プログラマ」(isbn:4881663763) によれば、## は 実際には、こんなふうに 使用されるらしい。(p128)

  1. /* country.c */
  2. #include
  3. #define NUM_CO(number) printf("country : %s\n", country ## mumber)
  4. main()
  5. {
  6. char *country01 = "U.S.A.";
  7. char *country81 = "Japan";
  8. NUM_CO(81);
  9. return 0;
  10. }