可变参数宏, Variadic Macros

可变参数宏, Variadic Macros


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

这里先讨论可变参数宏.


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


一, vc(C99)的复杂宏.


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


例如:


#include <stdio.h>

#define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }
#define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }
#define CHECK3(...) { printf(__VA_ARGS__); }

int main( )
{
	CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n");
	CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n");     // won't print
	CHECK2(0, "here %s %s %s", "are", "some", "varargs2(3)\n");     // won't print
	CHECK2(1, "here %s %s %s", "are", "some", "varargs2(4)\n");
	CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n");
	return 0;
}
 

输出为:


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))

你可能感兴趣的:(工作,gcc,Microsoft,vc++)