小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C語(yǔ)言宏嵌套

 renhl252 2015-03-21
C語(yǔ)言宏嵌套
【引用】C語(yǔ)言宏的嵌套問(wèn)題  http://zhangzhibiao02005.blog.163.com/blog/static/37367820201182585935895/ (修改原文第二個(gè)程序中一處錯(cuò)誤,return 1;改為return 0;CodeBlock下運(yùn)行驗(yàn)證,并附上不包含stdio頭文件的預(yù)處理后文件)
在C語(yǔ)言的宏中是容許嵌套的,其嵌套后,一般的展開(kāi)規(guī)律像函數(shù)的參數(shù)一樣,先展開(kāi)參數(shù),再分析函數(shù),所以展開(kāi)順序是由內(nèi)而外,但是當(dāng)宏中有#則不再展開(kāi)參數(shù)了,如果宏中有##,則先展開(kāi)函數(shù),再展開(kāi)里面的參數(shù)。
如下面的例子:
#include <stdio.h>
#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
int main()
{
    const char * str = TO_STRING(PARAM( ADDPARAM( 1 ) ) );
    printf("%s\n",str);
    str = TO_STRING2(PARAM( ADDPARAM( 1 ) ) );
    printf("%s\n",str);
    return 0;
}
它的輸出結(jié)果為:
"ADDPARAM( 1 )"
PARAM( ADDPARAM( 1 ) )
對(duì)于宏TO_STRING,它的定義中沒(méi)有#,所以先展開(kāi)里面的“PARAM( ADDPARAM( 1 ) )”,由于PARAM中有#,所以里面展開(kāi)的結(jié)果為ADDPARAM( 1 ),然后外面再展開(kāi),其結(jié)果為"ADDPARAM( 1 )"
而對(duì)于TO_STRING2,其定義中有#,所以直接展開(kāi),其結(jié)果為PARAM( ADDPARAM( 1 ) )
去掉include的預(yù)處理后文件為:
/*        6 */  int main ( )
/*        7 */  {
/*        8 */  const char * str = "\"ADDPARAM( 1 )\"" ;
/*        9 */  printf ( "%s\n" , str ) ;
/*       10 */  str = "PARAM( ADDPARAM( 1 ) )" ;
/*       11 */  printf ( "%s\n" , str ) ;
/*       12 */  return 0 ;
/*       13 */  }
注:\"為轉(zhuǎn)義字符反斜杠表示的雙引號(hào)。
而對(duì)于下面的例子:
#include <stdio.h>
#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
int main()
{
    const char *str = TO_STRING(TO_STRING2(PARAM( ADDPARAM( 1 ) ) ));
    printf("%s\n",str);
    return 0;
}
其輸出結(jié)果為:
a_PARAM( INT_1 )
因?yàn)槭紫确治鯰O_STRING的參數(shù)TO_STRING2(PARAM( ADDPARAM( 1 ) ) ),而對(duì)于TO_STRING2(x),由于其定義中有##,所以先展開(kāi)該函數(shù),其結(jié)果為a_PARAM(ADDPARAM( 1 )),而ADDPARAM( 1 )展開(kāi),結(jié)果為INT_1,所以其總結(jié)果為a_PARAM( INT_1 )
/*        6 */  int main ( )
/*        7 */  {
/*        8 */  const char * str = "a_PARAM( INT_1)" ;
/*        9 */  printf ( "%s\n" , str ) ;
/*       10 */  return 0 ;
/*       11 */  }
【引用結(jié)束】
【總結(jié)】
先展開(kāi)宏,再展開(kāi)宏參數(shù),這種說(shuō)法不太妥當(dāng),我總結(jié)的宏處理過(guò)程如下:
遇到宏名后(1)
  • 檢查對(duì)應(yīng)的宏體中是否含有#和##運(yùn)算符
    • 無(wú)——處理宏參數(shù)(實(shí)參)(2)
      •  遇到宏名,回到(1)
      • 沒(méi)有遇到,在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否遇到宏名(4)
        •  ...
    • 有——不檢查宏參數(shù),在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否含有宏名(3)
      • 遇到宏名,回到(1)
      •  沒(méi)有遇到,結(jié)束(5)
詳細(xì)地解釋一下整個(gè)過(guò)程并做驗(yàn)證
【經(jīng)典題過(guò)程】
#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)"     // 受字符串符號(hào)屏蔽
【對(duì)于那個(gè)討論帖的問(wèn)題】
#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過(guò)程】
遇到宏名后(1)
    檢查對(duì)應(yīng)的宏體中是否含有#和##運(yùn)算符
        無(wú)——處理宏參數(shù)(實(shí)參)(2)
            遇到宏名,回到(1)
            沒(méi)有遇到,在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否遇到宏名(4)
                ...
        有——不檢查宏參數(shù),在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否含有宏名(3)
            遇到宏名,回到(1)
            沒(méi)有遇到,結(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過(guò)程】
#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 )"




    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多