Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15364
  • 博文数量: 7
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 87
  • 用 户 组: 普通用户
  • 注册时间: 2017-05-12 16:45
文章分类

全部博文(7)

文章存档

2021年(1)

2017年(6)

我的朋友
最近访客

分类: C/C++

2017-05-27 20:28:39

最近被C语言中#和##的宏定义作用弄的有些头晕,花了点时间整理收集了一些内容,希望对大伙有点帮助吧,不多说,来干货。

宏中“#”的用法
1.可以把宏参数变为一个字符串
在一个宏中的参数前面使用一个#,预处理器会把这个参数转换为一个字符数组
e.p.
#include
#define STR(s) #s

int main()
{
    char* s = STR(patrickpan);
    printf("%s\n", p);
    return 0;
}

2.合并匿名变量名 
#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__在第二层才能被解开。


3.填充结构
#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"}};


4.分号吞食问题
有如下宏定义:
#define SKIP_SPACES(p, limit)  \
     { char *lim = (limit);         \
       while (p < lim) {            \
         if (*p++ != ' ') {         \
           p--; break; }}}
假设有如下一段代码:
if (*p != 0)
   SKIP_SPACES (p, lim);
else
    ...
这时如果编译的话,GCC将会报:error: 'else' without a previous 'if'。看似是一个函数的宏被展开为一段代码块,加上分号这个if逻辑块就结束了,所以比那一切发现这个else没有对于的if
这个问题一般用do{}while(0)的形式来解决;
#define SKIP_SPACES(p, limit)     \
     do { char *lim = (limit);         \
          while (p < lim) {            \
            if (*p++ != ' ') {         \
              p--; break; }}}          \
     while (0)
展开后就成了
if (*p != 0)
    do{...}while(0)
else
    ...
这样就可以消除分号吞噬问题。




宏中“##”的用法
1.##可以把两个宏参数粘合在一起
e.p.
#include
#include

#define MERGE(a,b) a##b
#define CONS(a,b) int(a##e##b)

int main()
{
    int t = MERGE(2,3);
    printf("t=%d\n", t);
    char* ab = "pantianxing";
    char* p = MERGE(a,b);
    printf("output:%s\n", p);
    printf("cons=%d\n",CONS(2,3));
    return 0;
}
输出如下:
t=23
ouput:pantianxing
cons=2000 // 2e3=2000



引用参考的文章如下:
http://idas643.blog.163.com/blog/static/1671048382015461049289/
http://www.voidcn.com/blog/earbao/article/p-6254938.html
http://cvrs.whu.edu.cn/blogs/?p=231


阅读(804) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~