• <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>
            BLUESKY
            一步一個腳印向前走

            今天在網上突然發現了下面幾個關于c代碼中的宏定義的說明,回想下,好像在系統的代碼中也見過這些零散的定義,但沒有注意,看到別人總結了下,發現果然很有用,雖然不知有的道可用與否,但也不失為一種手段,所以就先把它摘抄下來,增加一點見識:

            1,防止一個頭文件被重復包含
            #ifndef BODYDEF_H
            #define BODYDEF_H
              //頭文件內容
            #endif
            2,得到指定地址上的一個字節或字
            #define  MEM_B( x )  ( *( (byte *) (x) ) )
            #define  MEM_W( x )  ( *( (word *) (x) ) )
            3,得到一個field在結構體(struct)中的偏移量
            #define FPOS( type, field ) ( (dword) &(( type *) 0)-> field )
            4,得到一個結構體中field所占用的字節數
            #define FSIZ( type, field ) sizeof( ((type *) 0)->field )
            5,得到一個變量的地址(word寬度)
            #define  B_PTR( var )  ( (byte *) (void *) &(var) )
            #define  W_PTR( var )  ( (word *) (void *) &(var) )
            6,將一個字母轉換為大寫
            #define  UPCASE( c ) ( ((c) >= ''a'' && (c) <= ''z'') ? ((c) - 0x20) : (c) )
            7,判斷字符是不是10進值的數字
            #define  DECCHK( c ) ((c) >= ''0'' && (c) <= ''9'')
            8,判斷字符是不是16進值的數字
            #define  HEXCHK( c ) ( ((c) >= ''0'' && (c) <= ''9'') ||((c) >= ''A'' && (c) <= ''F'') ||((c) >= ''a'' && (c) <= ''f'') )
            9,防止溢出的一個方法
            #define  INC_SAT( val )  (val = ((val)+1 > (val)) ? (val)+1 : (val))
            10,返回數組元素的個數
            #define  ARR_SIZE( a )  ( sizeof( (a) ) / sizeof( (a[0]) ) )
            11,使用一些宏跟蹤調試
            ANSI標準說明了五個預定義的宏名。它們是:
            _LINE_ (兩個下劃線),對應%d
            _FILE_     對應%s
            _DATE_   對應%s
            _TIME_    對應%s
            _STDC_

             
            宏中"#"和"##"的用法
            我們使用#把宏參數變為一個字符串,用##把兩個宏參數貼合在一起.
            #define STR(s)     #s
            #define CONS(a,b)  int(a##e##b)
            Printf(STR(vck));           // 輸出字符串"vck"
            printf("%d\n", CONS(2,3));  // 2e3 輸出:2000

            當宏參數是另一個宏的時候
            需要注意的是凡宏定義里有用"#"或"##"的地方宏參數是不會再展開.
            #define A          (2)
            #define STR(s)     #s
            #define CONS(a,b)  int(a##e##b)
            printf("%s\n", CONS(A, A));               // compile error 
            這一行則是:
            printf("%s\n", int(AeA));
            INT_MAX和A都不會再被展開, 然而解決這個問題的方法很簡單. 加多一層中間轉換宏.
            加這層宏的用意是把所有宏的參數在這層里全部展開, 那么在轉換宏里的那一個宏(_STR)就能得到正確的宏參數
            #define STR(s)      _STR(s)          // 轉換宏
            #define CONS(a,b)   _CONS(a,b)       // 轉換宏
            printf("int max: %s\n", STR(INT_MAX));          // INT_MAX,int型的最大值,為一個變量 #include<climits>
            輸出為: int max: 0x7fffffff
            STR(INT_MAX) -->  _STR(0x7fffffff) 然后再轉換成字符串;

            printf("%d\n", CONS(A, A));
            輸出為:200
            CONS(A, A)  -->  _CONS((2), (2))  --> int((2)e(2))

            "#"和"##"的一些應用特例
            1、合并匿名變量名
            #define  ___ANONYMOUS1(type, var, line)  type  var##line
            #define  __ANONYMOUS0(type, line)  ___ANONYMOUS1(type, _anonymous, line)
            #define  ANONYMOUS(type)  __ANONYMOUS0(type, __LINE__)
            例:ANONYMOUS(static int);  即: static int _anonymous70;  70表示該行行號;
            第一層:ANONYMOUS(static int);  -->  __ANONYMOUS0(static int, __LINE__);
            第二層:                        -->  ___ANONYMOUS1(static int, _anonymous, 70);
            第三層:                        -->  static int  _anonymous70;
            即每次只能解開當前層的宏,所以__LINE__在第二層才能被解開;

            2、填充結構
            #define  FILL(a)   {a, #a}

            enum IDD{OPEN, CLOSE};
            typedef struct MSG{
              IDD id;
              const char * msg;
            }MSG;

            MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
            相當于:
            MSG _msg[] = {{OPEN, "OPEN"},
                          {CLOSE, "CLOSE"}};

            3、記錄文件名
            #define  _GET_FILE_NAME(f)   #f
            #define  GET_FILE_NAME(f)    _GET_FILE_NAME(f)
            static char  FILE_NAME[] = GET_FILE_NAME(__FILE__);

            4、得到一個數值類型所對應的字符串緩沖大小
            #define  _TYPE_BUF_SIZE(type)  sizeof #type
            #define  TYPE_BUF_SIZE(type)   _TYPE_BUF_SIZE(type)
            char  buf[TYPE_BUF_SIZE(INT_MAX)];
                 -->  char  buf[_TYPE_BUF_SIZE(0x7fffffff)];
                 -->  char  buf[sizeof "0x7fffffff"];
            這里相當于:
            char  buf[11]; 

             

            posted on 2007-11-20 12:12 LG 閱讀(17208) 評論(0)  編輯 收藏 引用 所屬分類: UnixProgram

            <2007年11月>
            28293031123
            45678910
            11121314151617
            18192021222324
            2526272829301
            2345678

            常用鏈接

            相冊

            最新評論

            国产成人精品久久一区二区三区av | AV无码久久久久不卡蜜桃 | 日本国产精品久久| 久久婷婷色综合一区二区| 久久精品人人做人人妻人人玩| 好属妞这里只有精品久久| 久久久免费观成人影院| 少妇高潮惨叫久久久久久| 国产成人精品久久一区二区三区av| 午夜精品久久久久久久无码| 国产美女久久精品香蕉69| 久久精品中文字幕第23页| 久久婷婷五月综合97色 | 日韩欧美亚洲综合久久| 99久久免费国产精精品| 久久综合亚洲色HEZYO社区| 国产精品久久自在自线观看| 午夜精品久久久久9999高清| 精品免费久久久久久久| 久久久久久精品免费看SSS| 国产精品伊人久久伊人电影| 欧美丰满熟妇BBB久久久| 国产精品99久久久久久宅男小说| 精品久久久无码中文字幕天天 | 亚洲国产另类久久久精品黑人| 久久国产精品视频| 久久精品国产91久久麻豆自制| 久久久久亚洲AV成人网人人网站 | 欧美精品丝袜久久久中文字幕 | 国产精品免费看久久久香蕉| 久久国产乱子伦免费精品| 伊人久久大香线蕉综合影院首页| 亚洲AⅤ优女AV综合久久久| 狠狠久久综合伊人不卡| 色噜噜狠狠先锋影音久久| 91久久成人免费| 91精品国产高清久久久久久91| 国产精品激情综合久久| 久久久久99精品成人片三人毛片| 国产精品伊人久久伊人电影| 久久久久国产一区二区|