(1)#
在一個宏中的參數前面使用一個#, 預處理器會把這個參數轉換爲一個字符數組
簡化理解:#是“字符串化”的意思,出現在宏定義中的#是把跟在後面的參數轉換成一個字符串
例如代碼:
#define ERROR_LOG(module) fprintf(stderr,"error: "#module"\n")
則:
ERROR_LOG("add"); 轉換爲 fprintf(stderr,"error: "add"\n");
ERROR_LOG(devied =0); 轉換爲 fprintf(stderr,"error: devied=0\n");
(2)##, “##”是一種分隔連接方式,它的作用是先分隔,然後進行強制連接,稱爲“記號粘合”。
在普通的宏定義中,預處理器一般把空格解釋成分段標誌,對於每一段和前面比較,相同的就被替換。但是這樣做的結果是,被替換段之間存在一些空格。如果我們不希望出現這些空格,就可以通過添加一些##來替代空格。
例如代碼:
#define A1(name, type) type name_##type##_type
#define A2(name, type) type name##_##type##_type
則:
A1(a1, int); /*等價於: int name_int_type; */
A2(a1, int); /*等價於: int a1_int_type; */
解釋:
1)在第一個宏定義中,"name"和第一個"_"之間,以及第2個"_"和第二個"type"之間沒有被分隔,所以預處理器會把name_##type##_type解釋成3段:“name_”、“type”、以及“_type”,這中間只有“type”是在宏前面出現過的,所以它可以被宏替換。
2)而在第二個宏定義中,“name”和第一個“_”之間也被分隔了,所以預處理器會把name##_##type##_type解釋成4段:“name”、“_”、“type”以及“_type”,這其間,就有兩個可以被宏替換了。
(3)延伸
#define A(x) T_##x #define B(x) #@x #define C(x) #x
我們假設:x=1,則有:
A(1) ------〉T_1
B(1) ------〉'1'
C(1) ------〉"1"