define常規的文字替換就不多說明了,
先說一下帶參數的宏替換,比如
#define add(x, y) (x + y)
需要注意的就是在涉及運算或着其他一些情況下,要加上括號來避免結合律影響運算結果,像5*add(2,3),你期望的結果是25,但是,在不加括號的情況下 5*2+3 結果是30.
當需要換行時,需要在行尾加上\ 比如:
1 #define NULL_RETURN(varName) \ 2 if(varName == nullptr) \ 3 { \ 4 return;\ 5 }
下面說下宏定義中的特殊操作符,包括#,##和__VA_ARGS__
#符號說白了就是可以把一個參數當作字符串來處理,避免參數替換,比如:
#define SQR(x) printf("the square of" #x "is %d.\n",(x)*(x))
當我們不希望printf中的x被參數替換時可以加上#號。
##符號簡單理解就是將兩個字符串拼接成一個,比如
#define PROPERTY_READONLY(varType, funName, varName) \ private: varType _##varName; \ public: varType get##funName() const { return _##varName; }
__VA_ARGS__ 是一個可變參數的宏,很少人知道這個宏,這個可變參數的宏是新的C99規范中新增的,目前似乎只有gcc支持(VC6.0的編譯器不支持)。
實現思想就是宏定義中參數列表的最后一個參數為省略號(也就是三個點)。這樣預定義宏__VA_ARGS__就可以被用在替換部分中,替換省略號所代表的字符串。
#define PR(...) printf(__VA_ARGS__) int main() { int wt=1,sp=2; PR("hello\n"); //輸出:hello PR("weight = %d, shipping = %d",wt,sp); //輸出:weight = 1, shipping = 2 return 0; }
省略號只能代替最后面的宏參數。
#define W(x,…,y)錯誤!
但是支持#define W(x, …),此時傳入的參數個數必須能夠匹配。
介紹幾個系統宏:
1) __FILE__ 預編譯時會替換成當前的源文件名
2) __LINE__ 預編譯時會替換成當前的行號
3) __FUNCTION__ 預編譯時會替換成當前的函數名稱
如何取消定義的宏呢,可以這樣做
//定義宏 #define [MacroName] [MacroValue] //取消宏 #undef [MacroName]
