關於巨集 define使用陷阱總結

2021-08-27 06:39:40 字數 1195 閱讀 4308

巨集定義發生在預編譯階段,簡單的說本質就是文字替換。使用時,有以下注意事項:

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,使用巨集定義,不允許引數發生變化,這也就是帶引數的巨集定義和函式的區別:

如下測試原始碼:

#include #define sqrt(a) ((a)*(a))

int fsqrt(int a)

int main()

最終的結果是a = 12; b = 11; r1 = 100; r2 = 100; 以上結果在vc6.0下獲得。之所以a變成12,是因為在替換的時候,a++被執行了兩次。要避免這種行為,就要使巨集引數不發生變化。

如:a++; r1 = sqrt(a), 一切就ok了!

3,使用大括號將巨集定義包含的多條表示式括起來。

如下示例:

#include #define initial(a, b)\

a = 0;\

b = 0;

int main()

結果列印a是正常的,但列印b卻是未初始化的結果。因為簡單的文字替換,不能保證多條表示式都放到for迴圈體內。(這裡,如果單獨初始化乙個變數,沒有for迴圈時沒有問題的。)上述的巨集定義應改為:

#define initial(a, b)\

注意這個「\」號哦,表示下面的一行和當前行在預編譯時被認為在同一行。

最後,再簡單對比下#define和 typedef的區別,#define發生在預編譯階段, typedef發生在編譯階段,可參考

。更多細節上的區別,稍後再談。

不對之處,大家多指正。

謹防define巨集陷阱

最近在研究deduplication 重複資料刪除 儲存技術,實現乙個dedup原型系統,結果在coding中遇到了乙個莫名其妙的問題。簡略 如下 include dedup.h ifndef block len define block len 32 1024 32k bytes endif de...

關於巨集定義 define

用來防止標頭檔案相互呼叫包含 ifndef test macro if not define define test macro define endif 有參巨集 define 巨集名 引數 例如 define can open first 0 define can open second 1 i...

define巨集定義的簡單總結

1 define pi 3.14159262 define char a a 3 define string a a 1 define square x x x 2 3 inta square 2 4 intb square 2 3 使用引數的巨集定義中,注意在巨集的替換主體部分對引數使用括號。上例...