Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329517
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2013-06-03 16:56:03

原文地址:

3.6 可变参数宏

宏可以像函数一样接受可变参数,定义方式跟函数相似,例如:
     #define eprintf(...) fprintf (stderr, __VA_ARGS__)

当可变参数宏被调用后,参数列表中的所有符号(包括逗号)都成为变量参数并替换__VA_ARGS__在宏中出现的位置。例如:
     eprintf ("%s:%d: ", input_file, lineno)
          ==>  fprintf (stderr, "%s:%d: ", input_file, lineno)

如果你觉得__VA_ARGS__太丑,想用漂亮的名字,比如SEX_VA。C预处理扩展,允许你写成“SEX_VA...”来作为可变参数,不使用__VA_ARGS__。例如:
    #define eprintf(SEX_VA...) fprintf (stderr, SEX_VA)

注意:不能用让这一扩展和__VA_ARGS__出现在同一个宏中。例如:

    #define eprintf(SEX_VA...) fprintf (stderr, __VA_ARGS__)

我们也可以在可变参数宏中定义命名参数,例如

     #define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)

上面宏看起来很不错,但是有一个不完美的地方。例如:

     eprintf("success!\n", );
          ==> fprintf(stderr, "success!\n", );
上面的写法会报错。因为标准C中不能忽略用来隔离命名参数和可变参数的逗号。

GNU的预处理使用两个扩展一起解决这个问题:
首先,取消逗号让可变参数为空。例如:
     eprintf ("success!\n")
          ==> fprintf(stderr, "success!\n", );
再次,使用有特殊意思的符号'##'放置在逗号与可变参数(__VA_ARGS__)之间。例如:


     #define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
当你eprintf宏被使用时,可变参数会被忽略,然后在'##'前的逗号会被删除掉。


测试代码:
#include 

#define eprintf_1(SEX_VA...) fprintf (stderr, SEX_VA)
#define eprintf_2(...) fprintf (stderr, __VA_ARGS__)
#define eprintf_4(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
#define eprintf_5(format, ...) fprintf (stderr, format, __VA_ARGS__)

int main(void)
{

    eprintf_1("1, ok : %d\n", 111);

    eprintf_2("2, ok : %d\n", 222);

    eprintf_4("4, ok : 444\n");

    eprintf_5("5, ok : %d\n", 555);


    return 0;
}


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