printf的宏定义

来源:互联网 发布:java 去除换行符 编辑:程序博客网 时间:2024/05/22 01:44

在程序中为了调试的方便经常会添加printf调试打印,但在产品正式发布时会将调试语句全部关掉,

这就涉及到如何关闭调试语句,可使用宏定义来达到调试的目的,如:

#define  DEBUG    printf

以后程序中就可以用

DEBUG("hello world\r\n");

要关闭调试语句时可以定义宏为:

#define DEBUG(fmt , ...)

即定义一个空宏即可,这样调试语句就会被编译器自动优化掉;

但这样做会有一个问题,如:

if(i > 0)

DEBUG("i > 0 \r\n");

i = 0;

上述程序片段的本意是在i大于0时打印,然后再使i等于0,即if语句只作用到DEBGU,

而不包含i = 0;这句话,但如果将调试关掉后程序就变成了

if(i > 0)

i = 0;

即if语句作用到了i = 0;这句话中去了,显然这违背了程序的本意;

因此我们就可以将if语句加上括号{ },不就可以啦,但你并不能要求所有代码人员都这么做,

况且if语句本身只包含一条语句时,是可以不用加括号的,因此别人不加括号也无可厚非,

那么程序就只能从宏定义本身入手了,这时我们可以用do{ ...}while(0)语句来实现:即

#define  DEBUG    do{  }while(0)

这样程序就被展来为:

if(i > 0)

do{  }while(0);

i = 0;

其中do{ }while(0);并未做任何实质的事情,但那完全可以限制住if语句的作用域,这样程序

就不会产生错误,同时do{ }while(0);语句也会被优化掉。

同理我们也可将调试宏定义修改为:

#define  DEBUG(fmt, ...) do{ printf(fmt , ##__VA_ARGS__); }while(0)

这样调试宏定义就显得比较完美了,其中DEBUG(fmt, ...)中的fmt 为调试格式字符串,后面

的省略号表示其参数是可变的,而printf(fmt , ##__VA_ARGS__); 中的fmt 字符串可以完

全替代过来,而后面的__VA_ARGS__表示参数的具体内容,这在编译时会被编译器确定下来,而前面

的##连词符表示如果调试语句不带参数,就将将面的逗号去掉,以防语法出错,这样宏定义

就算彻底完美了。


#define DEBUG_EN1 // 0: close debug , 1: open debug

#if DEBUG_EN

    #define    DEBUG(fmt, ...)     do{ printf(fmt , ##__VA_ARGS__); }while(0)

#else

    #define    DEBUG    do{  }while(0)

#endif




0 0