在C/C++的宏中,”#”的功能是將其後面的宏參數進行字符串化操作(Stringfication),簡單說就是在對它所引用的宏變量通過替換後在其左右各加上一個雙引號。
而”##”被稱為連接符(concatenator),用來將兩個子串Token連接為一個Token。注意這裡連接的對象是Token就行,而不一定是宏的變量。還可以n個##符號連接n+1個Token,這個特性是#符號所不具備的。
凡是宏定義裡有用’#’或’##’的地方宏參數是不會再展開。
若要使’#’和’##’的宏參數被展開,可以加多一層中間轉換宏。加這層宏的用意是把所有宏的參數在這層裡全部展開,那麼在轉換宏裡的那一個宏就能得到正確的宏參數。
以下是測試代碼:
#include stdafx.h #includeusing namespace std; //test1 #define WARN_IF(EXP) if (EXP) fprintf(stderr, warning: #EXP ); //test2 #define STR(s) #s //test3 #define _STRI(s) #s #define STRI(s) _STRI(s) //轉換宏 //test4 #define paster(n) printf(token#n = %d , token##n) //test5 #define _CONS(a, b) int(a##+##b) #define CONS(a, b) _CONS(a, b) //轉換宏 //test6 #define _GET_FILE_NAME(f) #f #define GET_FILE_NAME(f) _GET_FILE_NAME(f) //轉換宏 //test7 #define _TYPE_BUF_SIZE(type) sizeof #type #define TYPE_BUF_SIZE(type) _TYPE_BUF_SIZE(type) //test8 #define D(x) #@x //僅對單一標記轉換有效 int main(int argc, char* argv[]) { //test1 int divider = 0; WARN_IF(divider == 0);//warning: divider == 0 //test2 printf(int max: %s , STR(INT_MAX));//int max: INT_MAX //test3 printf(int max: %s , STRI(INT_MAX));//int max: 2147483647 //test4 int token9 = 9; paster(9);//token9 = 9 //test5 int A = 15, B = 2; printf(A + B = %d , CONS(A, B));//A + B = 17 //test6 char FILE_NAME[] = GET_FILE_NAME(__FILE__); cout<