可变参数宏定义
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
- #include
- #include
- #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 .\n", num);
- return num;
- }
- int main()
- {
- test();
- printf("--------ok-------\n");
- return 0;
- }
来源: http://www.bubuko.com/infodetail-3330507.html