1. 程式人生 > >使用#define定義字面值和偽函式

使用#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!");