• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            tqsheng

            go.....
            隨筆 - 366, 文章 - 18, 評論 - 101, 引用 - 0
            數據加載中……

            define 參數

            C99標準之宏定義_可變參數宏_#_##

                    在查看Android的log功能代碼的時候發現了如下宏定義:

            #define LOGV(...) ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))

                    參考如下鏈接和C99標準編寫測試代碼及輸出測試如下:

             

                    鏈接地址:

                             http://topic.csdn.net/u/20090311/22/dada8228-9254-47da-b88a-4895fd83ddde.html

                             http://www.vimer.cn/2010/03/cc%E5%AE%8F%E5%AE%9A%E4%B9%89%E7%9A%84%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0.html

                             http://www.uml.org.cn/c%2B%2B/200902104.asp

                             http://baike.baidu.com/view/1967819.htm?fr=ala0_1

                             http://eelab.tsinghua.edu.cn/book/09-11/856891276060145.html

                             http://blog.csdn.net/chenglian_999/archive/2009/11/04/4765317.aspx

             

                    語法解釋:

                    在最前強調一點,#和##只有在宏定義中有效,其他地方無效

                    #(可以稱之為hash字符,the # operator,#運算符),它的作用就是將它后面的東西轉換成字符串。它的作用可以通過測試代碼中的宏定義的#define LOGD部分注釋掉的代碼和未注釋掉的代碼互換來進行理解。(紅色部分)

                    ##的作用是將前后兩部分粘合在一起,例子為

            #define HASH_HASH STR(# ## #)
            #define HASHTEST ####
            //--------notice about the space in #define--------------
            #define CONTACT(a, b) STR(a ## b)
            #define NOSPACE_CONTACT(a, b) STR(a##b)
            #define NEW_CONTACT(a,b) newfun(a HASH_HASH b) //a new token is not ever a ##
            #define _NEW_CONTACT(a,b) STR(newfun(a HASH_HASH b))
            //-------------------------------------------------

                    帶參數的宏定義的測試也是紅色字體部分,參考資料中解釋為:

            "..."代表可變參數列表, 如果它不是僅有的參數, 那么它只能出現在參數列表的最后. 調用這樣的函數宏時, 傳遞給它的參數個數要不少于參數列表中參數的個數(多余的參數被丟棄).
            通過__VA_ARGS__來替換函數宏中的可變參數列表. 注意__VA_ARGS__只能用于函數宏中參數中包含有"..."的情況.

             

                    測試代碼:

            #include <stdio.h>

            #define STR(s) #s
            //#define LOGD(...) printf(#__VA_ARGS__)
            #define LOGD(...) printf(__VA_ARGS__)

            #define HASH_HASH STR(# ## #)
            #define HASHTEST ####
            //--------notice about the space in #define--------------
            #define CONTACT(a, b) STR(a ## b)
            #define NOSPACE_CONTACT(a, b) STR(a##b)
            #define NEW_CONTACT(a,b) newfun(a HASH_HASH b) //a new token is not ever a ##
            #define _NEW_CONTACT(a,b) STR(newfun(a HASH_HASH b))
            //-------------------------------------------------
            HASHTEST
            HASH_HASH
            NEW_CONTACT(I,m)
            CONTACT(I,m)
            NOSPACE_CONTACT(c,d)
            //------------------------------------------------

            int main()
            {

                    LOGD("This is a test for C99 #define!""/r/n");
                    LOGD(STR(Test STR defination)"/r/n");
                    LOGD(HASH_HASH"/r/n");
                    LOGD(CONTACT(I,m)"/r/n");
                    LOGD(NOSPACE_CONTACT(c,d)"/r/n");
                    LOGD(_NEW_CONTACT(I,m)"/r/n");
                    LOGD(STR(NEW_CONTACT(I,m))"/r/n");
                    return 0;

            }

             

                    使用gcc命令:

            gcc -E test.c

                    展開宏定義得到如下代碼:
            HASHTEST
            "##"
            newfun(I "##" m)
            "Im"
            "cd"


            int main()
            {

             printf("This is a test for C99 #define!""/r/n");
             printf("Test STR defination""/r/n");
             printf("##""/r/n");
             printf("Im""/r/n");
             printf("cd""/r/n");
             printf("newfun(I HASH_HASH m)""/r/n");
             printf("NEW_CONTACT(I,m)""/r/n");
             return 0;

            }


                    屏蔽不規范語法最后編譯執行的結果如下:

            This is a test for C99 #define!
            Test STR defination
            ##
            Im
            cd
            newfun(I HASH_HASH m)
            NEW_CONTACT(I,m)





            一般在調試打印Debug信息的時候, 需要可變參數的宏. 從C99開始可以使編譯器標準支持可變參數宏(variadic macros), 另外GCC也支持可變參數宏, 但是兩種在細節上可能存在區別.
            1. __VA_ARGS__
                    __VA_ARGS__ 將 "..." 傳遞給宏 . 如
                    #define debug(format, ...) fprintf(stderr, format, __VA_ARGS__)

            2. GCC的復雜宏
                    GCC使用一種不同的語法,從而可以給可變參數一個名字,如同其它參數一樣.
                    #define debug(format, args...) fprintf (stderr, format, args)
                    這和第一條的宏例子是完全一樣的,但是這么寫可讀性更強并且更容易進行描述.

            3. ##__VA_ARGS__
                    上面兩個定義的宏,如果出現 debug("A Message")的時候,由于宏展開后有個多余的逗號,所以將導致編譯錯誤.
                    為了解決這個問題,CPP 使用一個特殊的"##"操作,格式如下:
                    #define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
                    這里,如果可變參數被忽略或為空,"##"操作將使預處理器(preprocessor)去除掉它前面的那個逗號.


            posted on 2012-03-19 11:28 tqsheng 閱讀(1657) 評論(0)  編輯 收藏 引用

            国产99久久久国产精品~~牛| 99热精品久久只有精品| 久久人人爽人人爽人人片AV不| 欧美一区二区久久精品| 久久偷看各类wc女厕嘘嘘| 国产成人精品久久一区二区三区av | 精品精品国产自在久久高清| 久久精品男人影院| 怡红院日本一道日本久久| 久久精品久久久久观看99水蜜桃| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 国产精品99久久精品爆乳| 精品久久久久久久久免费影院 | 亚洲午夜久久久久妓女影院| 国产精品99久久久久久www| 99久久精品免费看国产一区二区三区 | 久久综合九色欧美综合狠狠| 久久香蕉超碰97国产精品 | 人妻无码αv中文字幕久久琪琪布| 久久香蕉一级毛片| 久久久久久午夜成人影院| 国产精品无码久久四虎| 综合久久国产九一剧情麻豆| 91久久精品视频| 国产69精品久久久久777| 久久久噜噜噜www成人网| 久久笫一福利免费导航| 久久天天躁狠狠躁夜夜2020老熟妇| 久久精品中文字幕久久| 国产91色综合久久免费| 久久99精品国产麻豆| 亚洲成色www久久网站夜月| 久久亚洲日韩看片无码| 久久亚洲AV成人无码软件| 国产精品成人久久久| 日产精品久久久久久久| 99久久国产精品免费一区二区 | 国产精品久久久久…| 久久精品国产亚洲av高清漫画| 久久精品人成免费| 99麻豆久久久国产精品免费|