可变参数宏

可变参数的宏

调试的时候需要打印一些调试信息,刚开始的做法如下:
1 #ifdef _DEBUG
2 // 打印调试信息

3 #endif

这样的代码写得多了,就觉得繁琐,于是我进行了改进如下: 

1 void DebugPrint(const char * format, ... );
2 #ifdef _DEBUG
3 #define DEBUG_PRINT DebugPrint
4 #else
5 #define DEBUG_PRINT    //此时用(...)替换宏DEBUG_PRINT。(其中...代表在release模式中传入DEBUG_PRINT的参数)
6 #endif

 这样就可以在调试模式下使用DEBUG_PRINT打印各种类型的数据。


自鸣得意了一段时间,忽然想到了一个问题,在Release模式下,语句:
1 DEBUG_PRINT("Hello, %s""World");

会被扩展成如下:

"Hello, %s", "World";

虽然这样子不会影响到程序的运行,但是万一产生某些副作用呢???于是到网上搜了一下,找到了下面的解决方案:
复制代码
1 void DebugPrint(const char * format, ... );
2 #ifdef _DEBUG
3 #define DEBUG_PRINT DebugPrint
4 #else
5 #define DEBUG_PRINT /\                    //此时,用//替换宏DEGUG_PRINT
6 / DebugPrint
7 #endif
复制代码
这样子改好后,在Release模式下,这个宏会被展开为一个注释,完全消除了副作用。
但是这种方法会用另外一个缺点,DEBUG_PRINT语句后面不能跟其他的可执行语句,否则在release模式下会被注释掉。

这时候我就想啊,如果C提供可变参数的宏该多好啊,想到了这里,忽然想到C99似乎有对可变参数宏的支持,
于是翻了一下书本,果然啊!

C99下,使用可变参数宏的方式如下:
一个例子,如下:
1 #define MyMax(...) max(__VA_ARGS__)
其中省略号(...)表示可变参数,和C函数的可变参数表示法一样;__VA_ARGS__决定了可变参数在何处被替换。
对于语句:
MyMax(a, b); 
会被替换为:
max(a, b);

将之应用于我的需求,可以修改如下:
复制代码
1 void DebugPrint(const char * format, ... );
2 #ifdef _DEBUG
3 #define DEBUG_PRINT(format, ...) DebugPrint(format, __VA_ARGS__)
4 #else
5 #define DEBUG_PRINT(format, ...)       //此时,用“空格”替换宏函数DEGUG_PRINT(format,...)(因为没有宏函数的实现体)
6 #endif
复制代码
现在好了,如果在release模式下,DEBUG_PRINT会被替换为空格,再也没有副作用了。

针对C99的方式,我做了一下实验:
在VC2008下运行良好,但是悲催的VC6却不支持,不过想想也是,VC6诞生的时候C99不知道还在哪呢!

注意:也可以将可变参数"..."定义为"arg...",在使用可变参数时候用##连接符实现:

    #define DEBUG_PRINT(format,arg ...)  \

              DebugPrint(format, ##arg)
 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值