#と##演算子
文字列化演算子
マクロ関数だけで使用できる、便利な演算子が用意されています
そのひとつが文字列化演算子です
マクロ関数で受け取った値に対して#記号をつけることで
それを文字列、すなわちダブルクォーテーションをつけた状態に置換えます
(プリプロセッサディレクティブであることを忘れないでください。あくまでソース上で置き換わるだけです)
#define STRING(str) #str
このマクロ関数は、仮引数の値をダブルクォーテーションをつけた状態に置き換えます
次のプログラムを実行してください
#include <stdio.h>
#define PRINT(str) printf(#str "\n")
#define STRING(str) #str
int main() {
PRINT(Kitty on your lap);
printf("%sバイトは1キロバイト" , STRING(1024));
return 0;
}
PRINT()マクロ関数には、ダブルクォーテーションは使用していません
しかし、この値は#演算しによって文字列かされるので、正常に作用します
次のような結果になりました
Kitty on your lap
1024バイトは1キロバイト
文字列に置き換えられていることがよくわかりますね
この置換えは、文字列内に頻繁に " が出てくる場合に便利です
普段ならば \" を何度も記述する必要がありましたが、#演算子を使えばその必要はありません
#include <stdio.h>
#define PRINT(str) printf(#str "\n")
int main() {
PRINT("ひざの上の同居人\"パートナー\" 〜 Kitty on your lap");
return 0;
}
このプログラムを実行すると、次のような結果になります
"ひざの上の同居人\"パートナー\" Kitty on your lap"
"や\記号も置き換えられているのがわかりますね
「 " 」 は 「 \" 」 に置き換えられ、「 \ 」 は 「 \\ 」 に置き換えられます
"ひざの上の同居人\"パートナー\" 〜 Kitty on your lap"
↓
\"ひざの上の同居人\\\"パートナー\\\" 〜 Kitty on your lap\"
結果として、printf("\"ひざの上の同居人\\\"パートナー\\\" 〜 Kitty on your lap\"\n")に置き換えられています
なんだかややこしいですが、このような置換えに便利だということはわかっていただけたと思います
トークン連結演算子
次はトークンを接合する演算子を紹介します
この演算子は、通常のマクロと関数マクロで有効です
トークンを接合するというのは、名前(たとえば変数名)を指定するのに
二つの文字をくっつけて置き換える作業です
トークン連結には##を使用します
左辺 ## 右辺
左辺と右辺には、それぞれのトークンを指定します
##によって、この二つのトークンが接合されて置き換えられます
つまり a ## 1 と指定すると、a1に置き換えられるという仕組みです
#include <stdio.h>
#define var(i) printf("var" #i " = %d\n" , var ## i)
int main() {
int var1 = 10 , var2 = 20;
var(1);
var(2);
return 0;
}
このプログラムを実行すると、次のような結果になります
var1 = 10
var2 = 20
見事に置き換えられています
例として var(1) は、次のように置き換えられています
printf("var" "1" " = %d\n" , var1)
このほかにも、Microsoft社のコンパイラ(VC++)であれば、固有の仕様で #@ 演算子というのもあります
#@は文字定数への置換えですが、ANSI C標準ではないので使用は推奨されません