问题提出
我们在调试程序时,输出调试信息(又称为”打桩”或者”插桩”)是一种普遍、有效的方法。
我们输出的信息通常包括行号、函数名、程序变量等。
但是我们在程序BUG修复后,又会特别烦我们之间插入的哪些调试语句,客户是不会理解我们那些调试语句曾经又多少汗马功劳,而太多的调试语句也影响我们程序运行时输出的美观和清晰,于是很多情况下我们需要手动将那些调试语句注释掉或者删掉,这对于小项目来说,我们还可以忍受,但是对于大项目,如果我们还是手动删除,我们只能。。。。呵呵,这不是程序猿该干的事。。。
下面我们给出几种调试方式方便大家使用。
手工环境下BUG程序中的调试信息
/* debug.c */
#include
#include
//#define DEBUG
/* 计算n的阶乘n! */
long Fac(int n);
/* 主函数 * 输入一个n计算n的阶乘 */
int main(void)
{
int n;
long fac;
while(scanf("%d", &n) != EOF)
{
printf("%d! = %ld\n", n, Fac(n));
}
return EXIT_SUCCESS;
}
/* 计算n的阶乘n! */
long Fac(int n)
{
int i;
long fac;
for(i = 1; i <= n; i++)
{
fac *= i;
printf("调试信息 %d! = %ld\n", i, fac);/* 调试信息 */
}
return fac;
}
这个程序是有BUG的,在程序第40行,变量fac未初始化为1。
插入的调试信息
printf("%d! = %ld\n", i, fac);/* 调试信息 */
在不需要时我们只能将此调试信息注释掉,这个是最原始,最人工的一种方式。
优势:
方便简单,易于操作,简单易读
缺点:
非常灵活,单一的调试信息会造成错误输出过于冗余
用预处理指令封装调试信息
通过预处理指令将调试信息封闭起来,如下
#ifdef DEBUG
printf("%d! = %ld\n", i, fac);
#endif
这样调试的信息只存在与插桩信息宏DEBUG的预处理指令下,如果需要打开调试信息就定义插桩信息宏DEBUG,否则就将插桩信息宏DEBUG注释掉(也可以undef或者删掉)。
这样我们的代码就变成
/* debug.c */
#include
#include
/* 插桩信息宏 */
#define DEBUG /* 如果需要调试信息请使用该宏,如果想取消调试信息,请注释掉或者*/
//#undef DEBUG /* 取消插桩信息宏DEBUG */
/* 计算n的阶乘n! */
long Fac(int n);
/* 主函数 * 输入一个n计算n的阶乘 */
int main(void)
{
int n;
long fac;
while(scanf("%d", &n) != EOF)
{
printf("%d! = %ld\n", n, Fac(n));
}
return EXIT_SUCCESS;
}
/* 计算n的阶乘n! */
long Fac(int n)
{
int i;
long fac;
for(i = 1; i <= n; i++)
{
fac *= i;
#ifdef DEBUG
printf("调试信息 %d! = %ld\n", i, fac);
#endif