1、第八章 程序调试8.1 程序错误分类 VB 中常见的程序错误可分为编译错误、运行错误和逻辑错误 3 类。1.编译错误编译错误也称为语法错误,在编写程序时,如果语句不符合 Visual Basic 的语法规则,就会产生这类错误。例如,输入了不正确的关键字、遗漏了某个必需的标点符号、缺少表达式、类型不匹配或者应该配对的语句没有配对等,都会产生编译错误。在编写代码或运行程序时,很容易检查出这类错误。在编写代码时,VB 会自动对程序进行语法检查,某些类型的语法错误能够被即时检查出来,并且会弹出一个出错消息框,出错的那一行以高亮度显示。例如,当输入“I=”后没有接着输入表达式,而是切换到其他行,则会弹出
2、如图 8.1 所示的消息框。还有一些类型的语法错误,在编写代码时 VB 检查不出来,例如,If 语句后没有对应的End If 语句、输入了错误的属性名等。在运行程序时,VB 将弹出错误消息框,提示用户错误所在,如图 8.2 所示。8.2 调试工具栏为了调试程序的方便,用户可以使用 VB 的调试工其栏。在默认情况下,VB 界面上不显示调试工具栏。打开【视图】菜单,指向【工具栏】选项,则弹出【工具栏子菜单,执行其中的【调试】命令即可打开调试工具栏。其中各按钮的功能如表 8.1 所示。8.3 设置断点断点是告诉 VB 挂起程序执行的一个标记,当程序执行到断点处即暂停程序的执行,进入中断模式,此时可以
3、在【代码】窗口中查看程序内变量、属性的值。在代码中设置断点是常用的一种调试方法。在 VB 中,断点的设置有两种办法:(1)将光标放置在需要设置断点的地方,执行【调试】菜单中的【切换断点】命令或单击调试工具栏中的 l 切换断点 l 按钮,即可在该行语句上设置一个断点。(2)设置断点更简便的办法是,直接在要设置断点的行的左边单击鼠标。设置了断点的行将以粗体显示,并且在该行左边显示一个黑色的圆点,作为断点的标记。在代码中可以设置多个断点。设置完断点后,运行程序,运行到断点处,程序就暂停下来,进入中断模式。这时断点处语句以黄色背景显示,左边还显示一个黄色小箭头,表示这条语句等待运行。把鼠标光标移到各变
4、量处,会显示变量的当前值,如图 8.8 所示。只要再对设置有断点的行执行一次设置断点的操作,即可清除该行的断点。在需要设置断点的代码行前面添加一个 Stop 语句,也能起到断点的作用,在程序运行遇到 Stop 语句时,就会暂停下来。使用 Step 语句比设置断点更灵活,例如,可以让某个循环在循环指定次数后停止执行,进入到中断模式。8.4 跟踪程序的运行查找程序中的错误所在并不那么容易,有时需要一条语句一条语句地执行或者反复执行某段代码来检查错误所在,这些方法被称为跟踪程序的运行。1.“逐语句”跟踪“逐语句”执行代码就是一条语句一条语句地执行代码,每执行一条语句后,就暂停下来,为程序调试者提供分
5、析判断的机会。进入“逐语句” 方式跟踪程序执行的具体办法是执行【调试】菜单中的【逐语句】命令,或单击调试工具栏里的【逐语句】按钮。不过最常用的方法还是使用快捷键 F8,每按一次F8 键,程序就执行一条语句,调试者可以观察代码的流程和语句的执行情况。2.“逐过程”跟踪如果要调试的程序调用别的过程,而被调用过程已经经过了调试,确保能正确执行,那么在调试这个程序时,若使用“逐语句”去跟踪就会在调用时到被调用过程里去一句句地执行,这显然没有必要。这时最好的办法是采用“逐过程”跟踪,把被调用过程当作一条语句处理。如果在事件过程中没有调用其他过程,则“逐过程”跟踪与“逐语句”跟踪相同。进入“逐过程” 方式
6、跟踪程序执行的具体办法是执行【调试】菜单中的【逐过程】命令,或单击调试工具栏里的【逐过程】按钮,也可以使用快捷键 Shift+F8。当使用逐语句跟踪进入被调用过程后。如果从开始的儿条语句就断定出该过程没有问题,可以执行【调试】菜单中的【跳出】命令,从当前的过程中提前跳出,去执行过程调用者的下一条语句。单击调试工具栏中的【跳出】按钮或使用快捷键 Ctrl+Shift+F8 也可以跳出被调用的过程。3.运行到光标处在对程序进行跟踪时,总是要一条语句一条语句地执行,这样有时显得较繁琐。对于不感兴趣的代码部分可以略过,方法是首先将光标插入到需要停止运行的某行语句中,然后执行【调试】菜单中的【运行到光标
7、处】命令,则程序运行到光标处就会中断运行。这时,调试者可以逐语句或逐过程执行后面的代码。【运行到光标处】命令的快捷键是 Ctrl+F8。8.5 使用调试窗口在程序调试过程中,对调试者最为重要的信息是:在运行过程中各变量和表达式的值的变化情况。这些信息能够为调试者提供分析依据,从而做出正确的判断。为此,VB 提供了三个调试窗口,分别是立即窗口、本地窗口和监视窗口。在逐语句执行代码时,可以通过它们来监视变量或表达式的值。立即窗口在程序进入中断模式后,一般会自动弹出立即窗口,如果界面上没有显示出立即窗口,可以执行【视图】菜单中的【立即窗口】命令来打开它。单击调试工具栏中的【立即窗口】按钮也可以打开立
8、即窗口。通过立即窗口,即可以监视当前过程中各变量或属性的值,还可以重新为变量或属性赋值。1.通过立即窗口监视VB 把立即窗口看作为一个名称为 Debug 的对象,Print 是它的一个很重要的方法。在程序代码中添加如下语句:Debug.print 变量或属性就能够将变量或属性的值显示在立即窗口中了,从而达到监视变量与属性值的目的。例如,在计算数组各元素的总和时,在代码中添加一条“Debug.Print S”语句,如图 8.11中(a)图所示。运行程序,立即窗口中就会显示出数组元素每次累加的结果,如图 8.11中(b)图所示。更灵活的监视变量或属性值的方法是,在程序进入中断模式后,在立即窗口中直
9、接使用Print 语句来输出变量或属性的值。例如,将断点设置在语句“A=S/6 ”处,如图 8.12 中(a)图所示,运行程序,当程序中断后,在立即窗口中输入“Prints”,按回车键,则输出变量 S 当前的值。同理,也可以输出循环变量 i 的当前值,如图 8.12 中(b)图所示。2.给变量或属性赋值在中断模式下,利用立即窗口不仅能输出变量或属性的值,还能改变它们的值。在调试程序时,常常使用立即窗口给某变量赋予不同的值,然后配合 Print 语句的使用就可以观察到该变量值对其他变量值的影响。例如,在代码中设置两个断点,如图 8.13 中(a)图所示,运行程序,当程序的运行在第一个断点处停下来
10、时,在立即窗口中输入“S=5”,按回车键;继续运行程序,当程序的运行在第二个断点处停下来时,在立即窗口中输入“PrintS”,按回车键,则输出 S 的值为26,如图 8.13 中(b)图所示。可见,变量 S 的初值变为 5,而不在是代码中所赋予的初值 0。8.5.2 使用本地窗口利用本地窗口不但可以查看当前过程中的所有变量取值,而且还可以查看该窗体及其上所有控件的属性取值。在中断模式下,执行【视图】菜单中的【本地窗口】命令,或单击调试工具栏中的【本地窗口】按钮可以打开本地窗口。其中显示了当前过程中所有变量及其取值。在本地窗口的表达式列表中显示的“Me”是指本窗体,单击其左边的加号节点可以展开它
11、,其中列出了本窗体及其上所有控件的属性取值。在本地窗口中还可以更改变量与属性的取值,选中某属性或变量,然单击它们的取值,即可更改其值了。注意:在本地窗口中更改属性的值只是在本次运行时有效,并不是真正改变了对象的属性设置。在本地窗口最上一栏显示的是当前的过程,单击右边的显示有符号的按钮,可打开【调用堆栈】对话框,如图 8.16 所示。在调试包含复杂的嵌套过程调用的应用程序时,【调用堆栈】对话框有助于了解过程调用的嵌套关系。在【调用堆栈】对话框中列出了当前过程正在调用的所有其他过程。当前过程位于最底部,它调用的某过程位于其上;该过程调用的另一过程又位于该过程的上面。因此,位于最上面的是最后调用的过
12、程。8.5.3 监视窗口监视窗口用来显示监视表达式的值,在使用该窗口前,需要事先添加要监视的表达式。为监视窗口添加监视表达式的方法有两种:1.使用【添加监视】对话框。(1)执行【调试】菜单中的【添加监视】命令,则弹出【添加监视】对话框,在【表达式】框中输入要监视的表达式,例如,要监视变量 S 的值,可以输入 S。(2)在【上下文】区中选择被监视的表达式所在的过程和模块。(3)在【监视类型】区中选择一种表达式的监视类型,如果选择【监视表达式】单项按钮,则监视窗口显示表达式的值。如果选择【当监视值为真时中断】单选按钮,则在程序运行中,当表达式的值为真(不为 0)时程序就进入到中断模式。如果选择【当
13、监视值改变时中断】单选按钮,则在程序运行中,一旦表达式的值改变,程序就进入到中断模式。(4)设置各选项,单击【确定】按钮即可为程序添加一个监视表达式。重复上述操作,可以添加多个监视表达式。2.使用【快速监视】对话框。(1)在【代码】窗口中选定要监视的表达式。(2)执行【调试】菜单中的【快速监视】命令,或单击调试工具栏中的【快速调试】按钮,打开【快速监视】对话框。(3)单击添加按钮即可将所选的表达式设置为监视表达式。在添加了监视表达式后,它们会出现在监视窗口中,如图 8.19 所示。还可以更改或删除已添加的监视表达式。在监视窗口中选中某表达式,执行【调试】菜单中的【编辑监视】命令,则弹出【编辑监
14、视】对话框,从中可以更改监视表达式及其各项设置,单击【删除】按钮可删除该监视表达式。8.6 错误捕捉一个好的应用程序,不仅体现在它的功能强大与容易操作,还体现在它良好完善的错误处理能力。在编写程序时,要充分考虑到程序运行时可能会遇到的错误。例如,在做除法运算时,用户输入的除数可能为 O;在执行读取软盘操作时,软驱里可能没有放软盘。当应用程序在 VH 环境中运行时,遇到错误将终止程序的运行,返回到 VH 环境。当应用程序被编译成 E文件,在 Windows 环境中运行时,一旦发生运行错误,Windows 将终止应用程序的执行,并将控制权交归还给 Windows 系统。显然,这种处理错误的方式不是
15、所希望的。一般的应用程序都会在运行时捕捉到错误,并且给出提示,以便让用户采取行动。在 VB 中,要增加应用程序的处理错误的能力,需要做以下两步工作:(1)设置错误陷阱(2)编写错误处理程序VB 提供了 On Error 语句设置错误陷阱,捕捉错误。On Error 语句有 3 种形式,如表 8.2所示。Resume 语句应放置在出错处理程序的最后,以便错误处理完毕后,指定程序下一步做什么。Resume 语句也有 3 种形式,如表 8.3 所示:在 On Error 语句捕捉到错误后,Err 对象的 Number 属性返回错误的代号,通过错误代号即可知道引发错误的原因了。在编写错误处理程序时,一般使用“IfErr.Number=”语句或“select Cage Err.Nurnber”语句来判断错误的类型:VB 提供的 Error 函数用于返回错误信息,其语法如下:Error(错误代号).例如:Form.Print.Error(11).语句将在窗体上显示“除数为零”。