可变参数宏, Variadic Macros

 可变参数宏, Variadic Macros


说起可变参数,立即想到的就是printf(),scanf()了.可变参数就是有一个固定的格式控制参数,后面再根据格式控制参数接若干参数.

这里先讨论可变参数宏.


我们一般在Debug需要打印调试信息的时候,需要可变参数的宏.


一, vc(C99)的复杂宏.


参考msdn(http://msdn2.microsoft.com/en-us/library/ms177415.aspx ).使用这种复杂宏时,省略号是格式控制参数,而标识符__VA_ARGS__用来插入另外的参数.__VA_ARGS__ 将"..." 传递给宏.


例如:


Cpp代码 
  1. #include <stdio.h>  
  2.   
  3. #define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }  
  4. #define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }  
  5. #define CHECK3(...) { printf(__VA_ARGS__); }  
  6.   
  7. int main( )  
  8. {  
  9.     CHECK1(0, "here %s %s %s""are""some""varargs1(1)/n");  
  10.     CHECK1(1, "here %s %s %s""are""some""varargs1(2)/n");     // won't print  
  11.     CHECK2(0, "here %s %s %s""are""some""varargs2(3)/n");     // won't print  
  12.     CHECK2(1, "here %s %s %s""are""some""varargs2(4)/n");  
  13.     CHECK3("here %s %s %s""are""some""varargs3(5)/n");  
  14.     return 0;  
  15. }  
 

 

输出为:


here are some varargs1(1)

here are some varargs2(4)

here are some varargs3(5)


二,GCC中的复杂宏


GCC支持C99中的复杂宏,但G++不支持.GCC使用一种不同的语法,给可变参数一个名字,如同其它参数一样.


#define CHECK1(x,format, args...) if(x) { printf (format, args); }


显然这样易于描述而且可读性更强.



三,CHECK("Some messges.")的情况


这时由于宏展开后有个多余的逗号,,将导致编译错误..为了解决这个问题,CPP使用一个特殊的“##”操作.


#define CHECK(format, ...) printf ( format, ## __VA_ARGS__)


这里,如果可变参数被忽略或为空,“##”操作将使预处理器去除掉它前面的那个逗号.如果在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面.


四,类似printf()的技巧


用一个被括弧括起来的 “参数”来定义和调用宏,参数在宏扩展的时候成为类似printf()函数中的格式控制字符串那样的参数列表.


#define CHECK(args) (printf("DEBUG: "), printf(args))

你可能感兴趣的:(c,工作,gcc,扩展,macros)