Chinaunix首页 | 论坛 | 博客
  • 博客访问: 252508
  • 博文数量: 54
  • 博客积分: 2915
  • 博客等级: 少校
  • 技术积分: 486
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-21 12:20
个人简介

这个人很懒,什么都没有留下

文章分类
文章存档

2013年(1)

2012年(6)

2011年(11)

2010年(16)

2009年(20)

我的朋友

分类: C/C++

2012-07-31 23:08:33

 ...在C宏中称为Variadic Macro,也就是变参宏。比如:
#define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)
  // 或者
#define myprintf(templt,args...) fprintf(stderr,templt,args)
第一个宏中由于没有对变参起名,我们用默认的宏__VA_ARGS__来替代它。第二个宏中,我们显式地命名变参为args,那么我们在宏定义中就可以用args来代指变参了。同C语言的stdcall一样,变参必须作为参数表的最后一项出现。当上面的宏中我们只能提供第一个参数templt时,C标准要求我们必须写成:
       myprintf(templt,);
的形式。这时的替换过程为:
       myprintf("Error!/n",);
  替换为:
      fprintf(stderr,"Error!/n",);
这是一个语法错误,不能正常编译。这个问题一般有两个解决方法。首先,GNU CPP提供的解决方法允许上面的宏调用写成:
      myprintf(templt);
而它将会被通过替换变成:
    fprintf(stderr,"Error!/n",);

    很明显,这里仍然会产生编译错误(非本例的某些情况下不会产生编译错误)。除了这种方式外,c99和GNU CPP都支持下面的宏定义方式:
#define myprintf(templt, ...) fprintf(stderr,templt, ##__VAR_ARGS__)
    这时,##这个连接符号充当的作用就是当__VAR_ARGS__为空的时候,消除前面的那个逗号。那么此时的翻译过程如下:
myprintf(templt);
  被转化为:
fprintf(stderr,templt);
这样如果templt合法,将不会产生编译错误。

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