使用#define定義字面值和偽函式
#define是C語言提供的巨集定義命令,能夠為程式設計師提供一定方便,在一定程度上提高程式的執行效率。
在程式中,有效範圍為巨集定義之後的本原始檔結束,在此檔案範圍內有效。另外,用#undef可以終止巨集定義的作用域,可靈活控制巨集定義的作用範圍。
(1)#define定義的常量無資料型別,只是簡單的字元替換,沒了型別的安全檢查,且有時還會產生邊際效應。
e.g:#define N100
#define M 200+N
當程式中使用M*N時,期望的結果是100*(200+N),實際結果是100*200+N
const常量就沒有這些問題。
(2)可以對const進行除錯,但無法對#define進行除錯
(3)const作用域僅限於區域性變數的函式體,但#define是從定義點到整個程式的結束點。不過可用#undef取消其定義,從而限定其作用域範圍。
(4)帶引數的巨集定義形式為:
#define <巨集名>(<引數表>)<巨集體>
#define MAX(x,y) (x)>(y)?(x):(y)
注意:在MAX(x,y)中不應該有空格,如果MAX(x,y),則最終替換的字元為a=MAX(x,y),將被展開為a=(x,y) (x)>(y)?(x):(y),問題就來了。
(5)使用do{}while(false)將巨集定義包含的多條表示式放到大括號中
使用巨集時,如果巨集包含多個語句,一定要用大括號把巨集括起來,以防在某些情況下,巨集定義的多條語句只有一條語句被執行。
(6)關於…的使用
#define myprintf(templt,…) fprintf(stderr,templt, _VA_ARGS_) //沒有對變參起名,用預設的巨集_VA_ARGS_來代替它
#define myprintf(templt,args…) fprintf(stderr,templt, args)
//顯示的命名變參為args,那麼在巨集定義中就可以用args來代替變參,變參必須作為引數表的最後一項出現
myprintf("Error!") ; 被替換成 fprintf(stderr,"Error!",);多了個逗號,會出現編譯錯誤
這時,就需要##了。##這個連線符號的作用是當_VA_ARGS_為空時,能夠消除前門的逗號,這樣就不會由語法錯誤啦。
#define myprintf(templt,…) fprintf(stderr,templt,## _VA_ARGS_)
myprintf("Error!") ; 被替換成 fprintf(stderr,"Error!");