乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C語言宏嵌套

       renhl252 2015-03-21
      C語言宏嵌套
      【引用】C語言宏的嵌套問題  http://zhangzhibiao02005.blog.163.com/blog/static/37367820201182585935895/ (修改原文第二個程序中一處錯誤,return 1;改為return 0;CodeBlock下運(yùn)行驗(yàn)證,并附上不包含stdio頭文件的預(yù)處理后文件)
      在C語言的宏中是容許嵌套的,其嵌套后,一般的展開規(guī)律像函數(shù)的參數(shù)一樣,先展開參數(shù),再分析函數(shù),所以展開順序是由內(nèi)而外,但是當(dāng)宏中有#則不再展開參數(shù)了,如果宏中有##,則先展開函數(shù),再展開里面的參數(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 ) )
      對于宏TO_STRING,它的定義中沒有#,所以先展開里面的“PARAM( ADDPARAM( 1 ) )”,由于PARAM中有#,所以里面展開的結(jié)果為ADDPARAM( 1 ),然后外面再展開,其結(jié)果為"ADDPARAM( 1 )"
      而對于TO_STRING2,其定義中有#,所以直接展開,其結(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)義字符反斜杠表示的雙引號。
      而對于下面的例子:
      #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 ) ) ),而對于TO_STRING2(x),由于其定義中有##,所以先展開該函數(shù),其結(jié)果為a_PARAM(ADDPARAM( 1 )),而ADDPARAM( 1 )展開,結(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é)】
      先展開宏,再展開宏參數(shù),這種說法不太妥當(dāng),我總結(jié)的宏處理過程如下:
      遇到宏名后(1)
      • 檢查對應(yīng)的宏體中是否含有#和##運(yùn)算符
        • 無——處理宏參數(shù)(實(shí)參)(2)
          •  遇到宏名,回到(1)
          • 沒有遇到,在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否遇到宏名(4)
            •  ...
        • 有——不檢查宏參數(shù),在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否含有宏名(3)
          • 遇到宏名,回到(1)
          •  沒有遇到,結(jié)束(5)
      詳細(xì)地解釋一下整個過程并做驗(yàn)證
      【經(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)的宏體中是否含有#和##運(yùn)算符
              無——處理宏參數(shù)(實(shí)參)(2)
                  遇到宏名,回到(1)
                  沒有遇到,在宏體中用實(shí)參字符串替換形式參數(shù),再檢查是否遇到宏名(4)
                      ...
              有——不檢查宏參數(shù),在宏體中用實(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 )"




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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多