1、宏定義不是C/C++語句,不需要使用語句結束符“;”,否則它也被看做宏體的一部分。
2、不要在引用宏定義的參數列表中使用增量和減量運算符,否則將導致變量的多次求值。例如:
#define SQUARE(x) ((x) * (x)) int n1 = 5; int m1 = SQUARE(n1++); //m1 = 25,n1 = 7 int n2 = 5; int m2 = SQUARE(++n2); //m2 = 49,n2 = 7
3、帶參數的宏體和各個形參應分別用括號括起來,以免造成意想不到的錯誤。例如:
#define SQUARE(x) x * x int m = SQUARE(3 + 5); //將被擴展為m = 3 + 5 * 3 + 5
4、當不再使用某一個宏時,可以使用#undef來取消其定義,否則簡單地刪除宏定義會帶來許多編譯錯誤。
5、編譯偽指令#error用於輸出與平台、環境等有關的信息。例如:
#if !defined(WIN32) #error ERROR: Only Win32 Platform supported! #endif #ifndef _cplusplus #error ERROR: MFC requires C++ compilation! #endif
當預處理器發現應用程序中沒有定義宏WIN32或者cplusplus時,把#error後面的字符序列輸出到屏幕後即終止,程序不會進入編譯階段。
6、當需要暫時放棄一段代碼的時候,如果這段代碼本身就含有塊注釋時,使用塊注釋屏蔽它就比較麻煩,此時可使用條件編譯偽指令#if來屏蔽這段代碼。例如:
#if 0 …//希望屏蔽的代碼 #endif
注意:由於條件編譯由編譯預處理器來處理,顯然預編譯偽指令無法計算有變量參與其中的表達式或sizeof表達式,只能用常量表達式。
7、編譯偽指令#pragma用於執行語言實現所定義的動作,例如:
#pragma pack(push, 8) /*對象成員對齊字節數*/ #pragma pack(pop) #pragma warning(disable:4069) /*不要產生第C4096號編譯警告*/
8、構串操作符#只能修飾帶參數的宏的形參,它將實參的字符序列(而不是實參代表的值)轉換成字符串常量。例如:
#define STRING(s) #s #s #s #define TEXT(s) "class" #s "Infor" int abc = 100; STRING(abc) //展開為abcabcabc TEXT(abc) //展開為classabcInfor
注意:無論#s之間有多少個空格展開後都將忽略。
9、合並操作符##將出現在其左右的字符序列合並成一個新的標識符(注意,不是字符串)。例如:
#include#define paster( n ) printf( "token"#n" = %d\n", token##n ) int main(void) { int token9 = 100; paster(9); //輸出token9 = 100 return 0; }