平时在Linux平台写代码的时候,虽然gdb的调试功能很强大,但很多时候我更喜欢调用系统打印函数来调试我的程序,可是直接调用的话难免显得很愚蠢(中国好像就是不缺愚蠢的coder),除非我需要打印的地方不超过3处,否则我是绝对无法容忍的,可是应该怎么做呢,别急,先去倒杯白开水,然后随便泡点什么,再坐下来一步一步慢慢的整理。
首先要先明确自己的需求,限于是初级篇,所以我设定的需求是:
- 可以像系统打印函数一样打印信息;
- 使用上不能比系统打印函数更复杂;
- 可以自动输出打印信息的具体位置;
- 具备统一开启和关闭打印功能;
要满足以上需求,好像没有比宏定义更好的解决方案了,先来看一个GCC风格的:
#define mydebug(format, args...) printf(format, ##args)
如果你并不使用GCC来编译你的C程序,那么可以使用C99风格的方式:
#define mydebug(format, ...) printf(format, ##__VA_ARGS__)
至于用哪一种,我的建议是:虽然GCC风格的可读性更好一点,但毕竟它不是C语言的标准,所以还是用标准风格吧。也许有人会对‘##’有所疑问,其实它的主要作用就是连接前后两个参数,如果后一个参数为空,就会去掉多余的逗号,防止语法上出现错误。
到目前为止上面的宏定义只能满足前两个需求,下面让我们来看看第三个需求,这时就需要用到一些标准预定义宏:
- __LINE__:在源代码中插入当前源代码行号
- __FILE__:在源文件中插入当前源文件名
- __DATE__:在源文件中插入当前的编译日期
- __TIME__:在源文件中插入当前编译时间
- __func__:在源代码中插入当前函数名
- __STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1
- __cplusplus: 当编写C++程序时该标识符被定义
好像函数名相关的宏还有__FUNC__, __FUNCTION__,至于到底用哪一个,我想说的是“标准才是王道”。有了这些宏,剩下的问题就很简单了,现在让我们一次性解决所有的需求,看剑:
#if 1 #define mydebug(format, ...) printf("[%s:%d] "format"", __FILE__, __LINE__, ##__VA_ARGS__) #else #define mydebug(format, ...) #endif
目前这种方式是最初级的定制,应付小规模的调试足够了,如果觉得上面的格式不喜欢,可以尽情的去改成你喜欢的格式,我只是提供了一份模板而已,鉴于本篇的主题,所以不再进行深入的探讨,下一节,我会让我们的打印函数具有等级的概念,还会根据不同的等级输出不同的颜色,敬请期待......