C语言 宏定义之可变参数

可变参数宏定义

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;
}
原文地址:https://www.cnblogs.com/zhanggaofeng/p/12037771.html