可变参数宏定义
C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏。可变参数宏就像下面这个样子:
#define dbgprint(...) printf(__VA_ARGS__)
缺省号代表一个可以变化的参数表。使用保留名 __VA_ARGS__ 把参数传递给宏。当宏的调用展开时,实际的参数就传递给 printf()了。
可变参数宏不被ANSI/ISO C++ 所正式支持。因此,你应当检查你的编译器,看它是否支持这项技术。
用GCC和C99的可变参数宏, 更方便地打印调试信息
#ifdef DEBUG #define dbgprint(format, ...) fprintf(stderr, format, __VA_ARGS__) #else #define dbgprint(format, ...) #endif
在标准C里,你不能省略可变参数,但是你却可以给它传递一个空的参数。例如,下面的宏调用在ISO C里是非法的,因为字符串后面没有逗号:
dbgprint ("A message")
GNU CPP在这种情况下可以让你完全的忽略可变参数。在上面的例子中,编译器仍然会有问题(complain),因为宏展开后,里面的字符串后面会有个多余的逗号。
为了解决这个问题,CPP使用一个特殊的'##'操作。书写格式为:
#define dbgprint(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
这里,如果可变参数被忽略或为空,'##'操作将使预处理器(preprocessor)去除掉它前面的那个逗号。
如果你在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,
它会把这些可变参数放到逗号的后面。象其它的pasted macro参数一样,这些参数不是宏的扩展。
/* C语言 宏定义之可变参数 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MDEBUG #ifdef MDEBUG #define TEST_LOG(format,...) fprintf(stderr, format, ##__VA_ARGS__) #else #define TEST_LOG(format,...) #endif int test() { int num = 10; TEST_LOG("my num is %d . ", num); return num; } int main() { test(); printf("--------ok------- "); return 0; }