对学过C语言的人来说,用注释法来调试代码,我想大家都不会太陌生。比如说,用“ // ”、“/* ...*/”先注释一部分代码,然后在逐一排查问题所在的位置。 也可以利用“注释+printf()”手段来进行调试。但要注意了,有时候我们仅凭一句printf()语句,输出结果并不立即显示在屏幕上,为什么呢?这是由于标准I/O缓冲区存在的缘故。这个问题的解决方法就是,在每个调试printf()函数之后立即调用fflush(stdout),详细内容可以自行查询有关于标准I/O的知识,在这里就不多累赘了。但如何利用条件编译来进行调试程序呢?下面,我们来讲一讲。 以互换2个数字为例,直接贴上代码:
#include <stdio.h>
int swap1(int a ,int b);
int swap2(int *p, int *q);
int main(void)
{
int a = 3;
int b = 5;
printf("---a = %d<-->b--- = %d.\n", a, b);
#ifdef DEBUG // 注意看这一部分
swap2(&a, &b); // 注意看这一部分
#endif // 注意看这一部分
swap1(a, b);
printf("---a = %d<-->b--- = %d.\n", a, b);
return 0;
}
int swap1(int a ,int b)
{
int t;
t = a;
a = b;
b = t;
}
int swap2(int *p, int *q)
{
int t;
t = *p;
*p = *q;
*q = t;
} 下面,我们主要来讲一下注释的那3行代码。
条件编译:
#ifdef 条件表达式
...
...(代码)
...
#endif意思是,
如果条件表达式为真,则执行正文里的代码,否则就不执行。语法就这么简单,所以那3行代码的意思是,如果定义了DEBUG,则执行swap2(&a, &b),否则就不执行。
当我们在linux平台下进行GCC编译时发现:
1>可以先用:gcc example.c -o example来查看结果时发现,a和b并没有交换数字。
结果1:
---a = 3<-->b--- = 5
---a = 3<-->b--- = 5
2>可以再用: gcc example.c -o example -DDEBUG查看时发现,a跟b确实互换数字。
结果2:
---a = 3<-->b--- = 5
---a = 5<-->b--- = 3
虽然上述代码比较简单,但思路很明确。当我们遇到代码量繁多又杂的情况时,利用条件编译手段来调试代码的优越性就体现出来了:你不必在一行一行的注释了,直接DEBUG,方便又快捷。
顺便补充一下,关于条件编译的另外两种形式:
形式2:
#ifndef _HEAD_H
#define _HEAD_H
...
...(代码)
...
#endif语法上是说,如果没有定义宏head.h,那么就定义head.h。这种目的是
为了防止头文件被重复包含。
形式3:
#ifdef 表达式
....
....(代码1)
....
else
....
....(代码2)
....
#endif语法跟形式1大体相同。如果表达式为真,则执行代码1,否则执行代码2。
注:如果以上办法都不能调试出错误,那么我们就只能够进行
GDB调试了。