宏定義發生在預編譯階段,簡單的說本質就是文本替換。使用時,有以下注意事項:
1,用宏定義表達式時,要使用完備的括號
如一下三個例子:
#define ADD(a,b) a+b
#define ADD(a, b) (a + b)
#define ADD(a, b) (a) +(b)
這三種定義,全部都是不符合要求的。陷阱如下:
在計算ADD(a,b)*ADD(c,d)時,顯然第一種出問題了。
#define MULTIPLE(a, b) (a*b) 在計算(a+b)*c時,調用MULTIPLE(a+b,c)得到的結果錯誤。
因此一定要使用完備的括號,如下示例:
#define ADD(a,b) ((a) + (b))
2,使用宏定義,不允許參數發生變化,這也就是帶參數的宏定義和函數的區別:
如下測試源碼:
[cpp]
<span style="font-size:18px;">#include <stdio.h>
#define sqrt(a) ((a)*(a))
int fsqrt(int a)
{
return a*a;
}
int main()
{
int a = 10, b = 10;
int r1, r2;
r1 = sqrt(a++);
r2 = fsqrt(b++);
printf("a = %d, b = %d, r1 = %d, r2 = %d\n", a, b, r1, r2);
return 0;
}</span>
最終的結果是a = 12; b = 11; r1 = 100; r2 = 100; 以上結果在vc6.0下獲得。之所以a變成12,是因為在替換的時候,a++被執行了兩次。要避免這種行為,就要使宏參數不發生變化。
如:a++; r1 = sqrt(a), 一切就ok了!
3,使用大括號將宏定義包含的多條表達式括起來。
如下示例:
[cpp]
<span style="font-size:18px;">#include <stdio.h>
#define INITIAL(a, b)\
a = 0;\
b = 0;
int main()
{
int a[5], b[5] ;
int i;
for(i=0; i<5; i++)
INITIAL(a[i], b[i]);
printf("a = %d, b = %d\n", a[0], b[0]);
return 0;
}</span>
結果打印a是正常的,但打印b卻是未初始化的結果。因為簡單的文本替換,不能保證多條表達式都放到for循環體內。(這裡,如果單獨初始化一個變量,沒有for循環時沒有問題的。)上述的宏定義應改為:
[cpp]
<span style="font-size:18px;">#define INITIAL(a, b)\
{\
a = 0;\
b = 0;\
}</span>
注意這個“\”號哦,表示下面的一行和當前行在預編譯時被認為在同一行。
最後,再簡單對比下#define和 typedef的區別,#define發生在預編譯階段, typedef發生在編譯階段,可參考http://topic.csdn.net/t/20030810/14/2129718.html。更多細節上的區別,稍後再談。
不對之處,大家多指正。