2009年1月31日土曜日

マクロ復習


このエントリーをはてなブックマークに追加


#define name 置換テキスト


関数と違う点



  • マクロはコンパイル時に置換される。



#define dprint(a) printf("result = %g\n", a)
dprint(a);//コンパイル後はprintf("result = %g\n", a);に置換


言い方は悪いが、普通のコードに置換されている。
そのため関数のようなオーバーヘッドがない。



  • 型指定がない。





有名な間違い



#define max(A,B) ((A) > (B) ? (A) : (B))
max(i++,j++) //間違い


インクリメントが複数回実効される。



#define square(x) x*x //間違い



square(z+1)だと
z+1*z+1=z+z+1=2z+1になってしまう。

正しくは、



#define square(x) ((x)*(x))



#記号(パラメータを実引数に置換)


#記号はパラメータを実引数に変換後、""で囲んでくれる。



#define dprint(expr) printf(#expr "= %g\n", expr)
dprint(x/y);

printf("x/y""= %g\n",x/y);

printf("x/y= %g\n",x/y);



##記号(文字列結合、引数呼び出し禁止)



#define cat(a,b) a ## b
cat(1,2);


##の隣の空白は削除されて文字列12になる。
また##のまわりでは引数展開できない(正確には不定)
つまり、
間違った予測では以下のようになる。



cat(cat(1,2),3);

cat(1,2) ## 3

(1 ## 2) ## 3

12 ## 3

123



実際は##のまわりでは引数展開が不定なので、



cat(cat(1,2),3);

cat(1,2) ## 3 //cat(1,2)は展開されない

cat(1,2)3



##を使わなければ可能



#define xcat(x,y) cat(x,y)
xcat(xcat(1,2),3);

123





0 件のコメント:

コメントを投稿