C語言宏嵌套 【引用】C語言宏的嵌套問題 http://zhangzhibiao02005.blog.163.com/blog/static/37367820201182585935895/ (修改原文第二個程序中一處錯誤,return 1;改為return 0;CodeBlock下運行驗證,并附上不包含stdio頭文件的預(yù)處理后文件) 在C語言的宏中是容許嵌套的,其嵌套后,一般的展開規(guī)律像函數(shù)的參數(shù)一樣,先展開參數(shù),再分析函數(shù),所以展開順序是由內(nèi)而外,但是當(dāng)宏中有#則不再展開參數(shù)了,如果宏中有##,則先展開函數(shù),再展開里面的參數(shù)。 如下面的例子:
它的輸出結(jié)果為:
對于宏TO_STRING,它的定義中沒有#,所以先展開里面的“PARAM( ADDPARAM( 1 ) )”,由于PARAM中有#,所以里面展開的結(jié)果為ADDPARAM( 1 ),然后外面再展開,其結(jié)果為"ADDPARAM( 1 )" 而對于TO_STRING2,其定義中有#,所以直接展開,其結(jié)果為PARAM( ADDPARAM( 1 ) ) 去掉include的預(yù)處理后文件為:
注:\"為轉(zhuǎn)義字符反斜杠表示的雙引號。 而對于下面的例子:
其輸出結(jié)果為:
因為首先分析TO_STRING的參數(shù)TO_STRING2(PARAM( ADDPARAM( 1 ) ) ),而對于TO_STRING2(x),由于其定義中有##,所以先展開該函數(shù),其結(jié)果為a_PARAM(ADDPARAM( 1 )),而ADDPARAM( 1 )展開,結(jié)果為INT_1,所以其總結(jié)果為a_PARAM( INT_1 )
【引用結(jié)束】 【總結(jié)】 先展開宏,再展開宏參數(shù),這種說法不太妥當(dāng),我總結(jié)的宏處理過程如下: 遇到宏名后(1)
詳細地解釋一下整個過程并做驗證 【經(jīng)典題過程】 #define f(a,b) a##b #define g(a) #a #define h(a) g(a) h(f(1,2)) (2) (1)(3)(5) h(12) (4) g(12) (1)(3)(5) "12" g(f(1,2)) (3) "f(1,2)" // 受字符串符號屏蔽 【對于那個討論帖的問題】 #define cat(a,b) a ## b #define f(a) fff a #define ab AB cat(cat(1,2),3) cat(1,2)3 cat(a,b) ab AB f(cat(cat(1,2),3)) fff cat(cat(1,2),3) fff cat(1,2)3 【例子1過程】 遇到宏名后(1) 檢查對應(yīng)的宏體中是否含有#和##運算符 無——處理宏參數(shù)(實參)(2) 遇到宏名,回到(1) 沒有遇到,在宏體中用實參字符串替換形式參數(shù),再檢查是否遇到宏名(4) ... 有——不檢查宏參數(shù),在宏體中用實參字符串替換形式參數(shù),再檢查是否含有宏名(3) 遇到宏名,回到(1) 沒有遇到,結(jié)束(5) #define TO_STRING2( x ) #x #define TO_STRING( x ) TO_STRING1( x ) #define TO_STRING1( x ) #x #define PARAM( x ) #x #define ADDPARAM( x ) INT_##x TO_STRING(PARAM( ADDPARAM( 1 ) ) ) TO_STRING("ADDPARAM( 1 )" ) TO_STRING1("ADDPARAM( 1 )" ) "\"ADDPARAM( 1 )\"" TO_STRING2(PARAM( ADDPARAM( 1 ) ) ) "PARAM( ADDPARAM( 1 ) )" 【例子2過程】 #define TO_STRING2( x ) a_##x #define TO_STRING( x ) TO_STRING1( x ) #define TO_STRING1( x ) #x #define PARAM( x ) #x #define ADDPARAM( x ) INT_##x TO_STRING(TO_STRING2(PARAM( ADDPARAM( 1 ) ) )) TO_STRING(a_PARAM( ADDPARAM( 1 ) )) TO_STRING(a_PARAM( INT_1 )) TO_STRING1(a_PARAM( INT_1 )) "a_PARAM( INT_1 )" |
|