專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

C語言中##的用法

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時間:2014年04月10日   【字體:
今天看linux操作系統(tǒng)源碼是有這么一段:
                                        #define _syscall0(type,name) \
                                        type name(void) \
                                        { \
                                        long __res; \
                                        __asm__ volatile ( "int $0x80" \ // 調(diào)用系統(tǒng)中斷0x80。
                                        :"=a" (__res) \ // 返回值??eax(__res)。
                                        :"" (__NR_
                                        ##name)); \ // 輸入為系統(tǒng)中斷調(diào)用號__NR_name。
                                         if (__res >= 0) \ // 如果返回值>=0,則直接返回該值。
                                          return (type) __res; errno = -__res; \ // 否則置出錯號,并返回-1。
                                          return -1;} 
其中有一個地方出現(xiàn)了兩個‘#’號不明白什么意思,網(wǎng)上找到了一段論壇:
     
 宏中"#"和"##"的用法 

一、一般用法 
我們使用#把宏參數(shù)變?yōu)橐粋€字符串,用##把兩個宏參數(shù)貼合在一起. 
用法: 
#include<cstdio> 
#include<climits> 
using namespace std; 

#define STR(s)     #s 
#define CONS(a,b)  int(a##e##b) 

int main() 

    printf(STR(vck));           // 輸出字符串"vck" 
    printf("%d 
", CONS(2,3));  // 2e3 輸出:2000 
    return 0; 


二、當(dāng)宏參數(shù)是另一個宏的時候 
需要注意的是凡宏定義里有用'#'或'##'的地方宏參數(shù)是不會再展開. 

1, 非'#'和'##'的情況 
#define TOW      (2) 
#define MUL(a,b) (a*b) 

printf("%d*%d=%d 
", TOW, TOW, MUL(TOW,TOW)); 
這行的宏會被展開為: 
printf("%d*%d=%d 
", (2), (2), ((2)*(2))); 
MUL里的參數(shù)TOW會被展開為(2). 

2, 當(dāng)有'#'或'##'的時候 
#define A          (2) 
#define STR(s)     #s 
#define CONS(a,b)  int(a##e##b) 

printf("int max: %s 
",  STR(INT_MAX));    // INT_MAX #include<climits> 
這行會被展開為: 
printf("int max: %s 
", "INT_MAX"); 

printf("%s 
", CONS(A, A));               // compile error  
這一行則是: 
printf("%s 
", int(AeA)); 

INT_MAX和A都不會再被展開, 然而解決這個問題的方法很簡單. 加多一層中間轉(zhuǎn)換宏. 
加這層宏的用意是把所有宏的參數(shù)在這層里全部展開, 那么在轉(zhuǎn)換宏里的那一個宏(_STR)就能得到正確的宏參數(shù). 

#define A           (2) 
#define _STR(s)     #s 
#define STR(s)      _STR(s)          // 轉(zhuǎn)換宏 
#define _CONS(a,b)  int(a##e##b) 
#define CONS(a,b)   _CONS(a,b)       // 轉(zhuǎn)換宏 

printf("int max: %s 
", STR(INT_MAX));          // INT_MAX,int型的最大值,為一個變量 #include<climits> 
輸出為: int max: 0x7fffffff 
STR(INT_MAX) -->  _STR(0x7fffffff) 然后再轉(zhuǎn)換成字符串; 

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

三、'#'和'##'的一些應(yīng)用特例 
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; 
即每次只能解開當(dāng)前層的宏,所以__LINE__在第二層才能被解開; 

2、填充結(jié)構(gòu) 
#define  FILL(a)   {a, #a} 

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

MSG _msg[] = {FILL(OPEN), FILL(CLOSE)}; 
相當(dāng)于: 
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、得到一個數(shù)值類型所對應(yīng)的字符串緩沖大小 
#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"]; 
這里相當(dāng)于: 
char  buf[11];
 自己在linux下編寫了一段程序:
#include<stdio.h>
#define transform 1##2##3
int main()
{
    int result=transform*transform;
    printf("the num of result is : %d",result);
    return 0;

函數(shù)輸出的結(jié)果是 15129(=123*123)--得出結(jié)論是:##的作用之一是將前后兩個宏參數(shù)連在一起!

關(guān)閉窗口

相關(guān)文章