ITPub博客

首页 > 应用开发 > > C语言中#和##的用法

C语言中#和##的用法

作者:fondtiger 时间:2019-09-04 15:15:50 0 删除 编辑

最近被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

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2508/viewspace-3151914/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-29

  • 博文量
    122
  • 访问量
    13449