C语言编程常见问题解答之调试

C语言编程常见问题解答之调试,第1张

C语言编程常见问题解答之调试,第2张

调试是指消除程序中的错误(通常称为bug)的过程。一个错误可以简单到拼错一个单词或者漏掉一个分号;它也可能很复杂,比如使用一个指向不存在的地址的指针。无论错误有多复杂,掌握正确的调试方法都能让程序员受益匪浅。

1.1如果正在运行的程序挂起,该怎么办?
当你运行一个程序时,有许多原因使它挂起。这些原因可以分为以下四种基本类型:
(1)程序中存在无限循环;
(2)程序运行时间比预期长;
(3)程序在等待一些输入信息,输入正确后才会继续运行;
(4)编程的目的是延迟或暂停执行一段时间。
讨论完不明原因挂起的程序的调试技巧后,将对以上每一种情况逐一分析。
调试由于未知原因而挂起的程序是非常困难的。你可能花了很长时间编写一个程序,试图确保每个代码都是准确的,或者你可能只是对一个运行良好的程序做了一个小小的修改,但是当你运行这个程序时,屏幕上什么也没有显示。如果你能得到一个错误的结果,或者部分结果,你可能知道应该修改什么,但是一个空白屏真的很让人沮丧,你根本不知道哪里错了。
当你开始调试这样的程序时,首先要检查程序结构,然后按照执行顺序检查程序的各个部分,看它们是否能正确运行。
例如,如果主程序只包含3个函数调用——A()、B()和C(),那么在调试时,可以先检查函数A()是否将控制权返回给主程序。为此,可以在调用函数A()的语句后添加exit()命令,或者用注释括起对函数B()和C()的调用,然后重新编译并运行该程序。

注意:这也可以通过调试器来完成,但是上面的方法是非常传统的调试方法。调试程序是一个程序,它的作用是使程序员能够观察程序的运行情况,程序当前的运行行号,变量的值等等。

此时,你会看到函数A()是否将控制权交还给主程序——如果程序运行并退出,你就可以判断是程序的其他部分让程序挂起了。你可以用这种方法测试程序的每一部分,直到找到挂起程序的部分,然后集中精力修改相应的函数。
有时候,情况更复杂。比如挂起程序的函数本身是完全正常的,问题可能是函数从别的地方得到了一些错误的数据。此时,您应该检查函数接受的所有值,并找出哪些值导致了错误的操作。

提示:监控功能是调试器的优秀功能之一。

分析下面这个简单的例子有助于你掌握这种技巧的使用:
# include
# include
*
*/[
*
*主程序
*/
int A()、B()、C();/*这些是其他某个
模块中的函数*/
int main()
{
int v1,v2,v3;
v1 = A();
v2 = B(v1);
v3 = C(v1,v2);
printf("结果为%d. \n ",v3);
return(0);
}

可以在调用函数a()的语句后输出变量v1的值,确认是否在函数b()可接受的值范围内,因为即使函数b()挂起了程序,也不一定是错的,可能是因为函数a()给了函数b()一个不是它所期望的值。
现在已经分析了调试“挂起”程序的基本方法,下面我们来看看一些常见的让程序挂起的错误。

无限循环
当你的程序出现无限循环时,机器会无数次执行同一段代码。这种操作当然不是程序员想要的。无限循环的原因是程序员总是让程序循环的判断条件为真,或者让程序退出循环的判断条件总是为假。下面是一个无限循环的例子:
/*初始化一个双维数组*/
for(a = 0;a < 10++ a)
{
for(b = 0;b {
array[a][b]= = 0;
}
}

这里的问题是程序员出错了(其实可能是打字母出错)。第二个循环应该在变量B增加到10后结束,但是变量B的值始终没有增加!第二个for循环的第三部分增加了变量A的值,而程序员打算增加变量b的值。因为b的值将始终小于10,所以第二个for循环将始终运行。
如何找到这个错误?除非你重读程序,注意到变量B的值没有增加,否则你是找不到这个错误的。在尝试调试程序时,可以在第二个for循环的循环体中添加这样的语句:
printf ("%d% d% d \ n ",a,b,array[a][b]);
这个语句的正确输出应该是:
000
010
(甚至达到)
990
但是你实际看到的是:
000[/br 0 0
...
你得到的是一个数列,第一项不断增加,但永远不会自行结束。用这种方法输出变量不仅可以找出错误,还可以知道数组是否由期望值组成。这个错误用其他方法似乎很难发现!这种输出可变内容的技能以后会用到。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C语言编程常见问题解答之调试

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情