vs2008简单调试方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VS2008简单调试方法
程序的错误通常可以分为若干类,语法错误,链接错误,逻辑错误。语法错误是比较容易查找并且修改的,而且编译给出的提示信息也比较完整,所以容易修改。链接错误来源很多,常常由于和系统、库函数等方面的原因出错,难以一言蔽之。最后是逻辑错误,也就是学生在实验课上碰到的难点,因为系统没有给出明确的提示,同学也只是知道运行错误,那么如何找到并修改运行错误就非常重要。下面以一个实例简单介绍一下调试过程,当然更加深入的还需自己多练习,学习。该文档所举例子为VS2008,同样适用于VS2005,VC++6。
1 一个实例
一个链表的程序,包括主程序Win32_C_Proj.cpp文件,Bucket.h和Bucket.cpp,其中Bucket用链表的方式实现一个容器。如下分别展示了main函数,bucket的插入元素函数和类的数据定义。
运行结果如下图
运行该程序,我们要的结果是1,2,因为是再第一位置插入1,第二位置插入2。而现在这个程序的输出结果却是2,1,和我们预想的不符合,说明程序设计过程中存在逻辑上的错误,也就是算法设计的问题。
2 初步发现问题
接下来第一步就是要发现问题。程序就那么几句,很明显,我们需要做的第一步就是确定错误的大至位置。
按F10运行程序,运行程序如下:
其中1位置是调试常有的工具按钮,2位置的箭头指示的是当前程序运行到的位置。工具按钮中八个按钮分别是:
●继续运行(F5,会运行到下一个断电停止,如果没有断点,则运行到结束)、
●停止运行(不结束程序ctrl+shift+F5)、
●结束运行(结束程序调试 shift+F5)、
●重新启动、
●显示下一个语句、
●运行到函数内部(如果当前语句是一个函数)(F11)
●运行到同层的下一条语句(F10)
●跳出当前函数(shift+F11)
我们按F10,运行到bucket1.insertElem(2,2),这时候箭头指向该语句,表示该语句前面的语句都运行完成,但是该语句还未运行,显示的监视窗口如下:
Bucket1变量展开之后可以看到,它包含size=1,head节点和currentNode。Head节点展开,其值data为-858993460(这个区域对链表头而言没有用),next又指向一个节点,所指节点值为1,next为空。这些结果和我们的预期一致,说明到目前为止没有发现错误。再按F10,运行的窗口监视变化为下图:
从这里观察head的next指向的节点值是2,2这个节点指向的值是1,很明显我们希望在第二个位置插入2,而不是第一个位置。因此可以断定刚才执行的这个语句有问题。
2 深入发现问题
在初步发现问题在InsertElem函数之后,接下来重新开始,并且在发现错误的这条语句上加断点(光标停留在该语句行,并且按F9),效果如下:
这样设置的目的是便于直接运行到该位置,特别在程序比较长的时候,如果再次从头一步一步运行非常耗时间,所以这里设置断点,然后按F5可以直接运行到该位置。我们让程序运行到该位置,效果如下:
这时候就需要进一步考察该函数运行了,因为我们已经断定这里存在错误。用F11让程序运行进入到该函数内部,效果如下:
接着按照前面的方法用F10让程序在该层逐步运行,并且对比你所预期的结果和程序运行的结果,如果不一致,便发现问题了。在本例中,要在第二个为止插入节点,那么for 语句应该执行一次,让p移动,而我在执行过程中发现,for语句没有进入内部执行,直接到如下为止,因此可以断定此处存在和预期不符合的情况。
再仔细推敲,很容易发现问题:for语句中的k初始为2导致p没有向后移动。
3 解决问题
发现问题后加以解决就非常方便了,只要把k的初始值改为1便可。至此,我们解决了一个逻辑错误。当然算法如果还有其它的错误,则还需要进一步发现。
4 其它
在程序较长的时候,特别是有循环存在的时候,可以适当设置若干个断点把程序分成几个部分,然后直接F5运行到断点,观察结果和预期效果。这样做的好处就是可以避免对长程序逐语句运行耗费很多时间,可以快速确定程序问题所在区域。然后在该区域内部再一步一步跟踪执行。
另外,在调试程序的时候,通常需要多遍运行,而不是一次就可以,所以很多同学一边运行一边输入数据的方法就非常麻烦。这时候可以把要输入的数据先固定存储成变量或者数组,避免每一次调试都要重新输入。待调试成功后再改回去便可。
5 运行变量的观察
运行过程中程序状态的监测实际上非常重要,常用的方法有打印输出,但是打印输出在有些情况下使用较为麻烦,有一定的局限性。VS已经提供了观察变量、调用堆栈的窗口,如下图,通常在VS的下部。
窗口的左边部分包括了几个页面,分别是:
⏹自动窗口:这里面是系统自动根据当前状况列出一些相关的变量,数据
⏹局部窗口:显示当前运行所在位置相关的局部变量
⏹线程:列出当前所有的线程
⏹模块:列出系统调用的各个模块
⏹监视1:可以根据自己的需要把一些变量列进去,以便观察。比如bucket1的地址,
这个在自动和局部窗口无法看到,这里可以通过&bucket1的方式增加进去。
窗口右边包含了如下几个页面:
⏹调用堆栈:列出了当前程序位置的调用过程,从下往上,可以观察到从到达当前函
数的路径。通常程序运行错误的时候就可以观察这里,找到程序停止的位置,帮助确定设置断点的位置等。
⏹断点:列出了所有设置的断点
⏹输出:没什么好说的,就是一些加载输出等。
作者:fjnuzs@