第7章 Delphi异常处理与调试
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第7章 Delphi异常处理与调试
7.1.2 错误类型
一般来说,无论在编程的时候如何仔细,程序总会有错 误。错误分为4种类型:设计期错误、编译期错误、运行期 错误、逻辑错误。 1. 设计期错误 这种错误类型发生在设计期,通常是因为给组件的某个 属性输入了非法的值。例如,在设计数据库应用程序时指定 了一个没有定义的数据库别名。
delphiHale Waihona Puke Baidu序设计基础教程
第7章 Delphi异常处理与调试
表7-1 整数异常及其产生原因
异 常 类 EDivByZero ERangeError EIntOverFlow 引 发 条 件 试图被零除 整数表达式越界 整数操作溢出
当一个整数表达式的值超过为一个特定整数类型分配的 范围时引发ERangeError异常。比如下面一段代码将引发一个 ERangeError异常。 var SmallNumber:ShortInt; X,Y:Integer; begin X:=100; Y:=75; SmallNumber:=X*Y; end;
7.1.1 异常处理的意义
异常可以理解为一种特殊的事件。当这种特殊的事件发 生时,程序正常的执行流程将被打断。异常处理机制能够确 保在发生异常的情况下应用程序不会中止运行,也不会丢失 数据或资源。 没有人能保证程序代码绝对不出错。有时候,即使程序 本身没有错,但与程序打交道的软、硬件设备出错,也会使 程序出现异常。引起异常的设备称为“异常源”,包括操作 系统、设备驱动程序、数据库驱动程序(诸如BDE、SQL Links、ODBC、ADO)、动态链接库、常驻内存的防病毒软 件、Delphi自身的组件库和运行期库等。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
7.2 Delphi异常类
异常类是Delphi异常处理机制的核心,也是Delphi异常 处理的主要特色。Delphi提供的所有异常类都是Exception类 的子类。用户也可以从Exception类派生一个自定义的异常 类。Exception的一系列构造函数中最重要的参数是显示的 错误信息。而数据成员中最重要的也是可被引用的消息字符 串(message,messagePtr)。从大的方面可以把异常类分为 运行库异常、对象异常、组件异常3类。 1. 整数异常 整数异常都是从一个EIntError类派生的,但程序运行中 引发的总是它的子类:EDivByZero、ERangeError和 EIntOverFlow,见表7-1。
这种类型的错误比较容易被发现和纠正,因为Delphi能 够对属性的值进行合法性检查。一旦发现这种错误,Delphi 将弹出一个警告窗口,提示用户纠正错误。
delphi程序设计基础教程
第7章 Delphi异常处理与调试 2. 编译期错误 编译期错误也叫语法错误,当程序代码违反了Object Pascal的语法 规则时将发生这种错误。 如果程序代码中有语法错误,编译就不能通过,代码编辑器的状态 栏将给出错误信息提示,并在代码编辑器中突出显示有语法错误的行。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
特定整数类型包括ShortInt、Byte以及与整数兼容的枚 举类型、布尔类型等,例如 : type THazard=(Safety,Marginal,Critical, Catastrophic); var Haz:THazard; Item:Integer; begin Item:=5; Haz:=THazard(Item); end;
delphi程序设计基础教程
第7章 Delphi异常处理与调试
4. 逻辑错误 逻辑错误是指程序通过了编译,也能执行,但执行的结 果与预期的不同。 逻辑错误有时比较难找,因为编译器无法识别这种错误。 此时,需要用内部集成调试器,通过控制程序的运行以及监 视程序的输出,来把错误逐步定位在一个较小的范围内。 5. 怎样尽可能地减少错误 虽然错误是很难避免的,但好的编程习惯能够尽可能地 减少错误。以下是一些有关编程习惯的建议。 1) 程序应尽可能地模块化 程序分解为模块后,由于每个模块所要完成的任务相对简单 了,所以发生错误的可能也就减少了。模块化还简化了程序 的维护。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
EIntOverFlow异常类在Integer、Word、Longint 3种整数类型越界 时引发。如下面的代码将引发一个EIntOverFlow异常。 var I:Integer; a,b,c:Word; begin a:=10; b:=20; c:=1; for I:=0 to 100 do c:=a*b*c; end; EIntOverFlow异常类只有在编译选择框 Option|Project|Over_Flow_Check Option选中时才产生。当关闭溢出检 查,则溢出后变量的值是丢弃溢出部分后的剩余值。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
2) 养成良好的代码书写习惯 注释能够增加代码的可读性,方便维护和修改。缩进能 够使程序的语法结构更加清晰。
3) 不要忘记检查参数的值
在函数内部,首先要检查传递过来的参数值是否合法, 是否在一个可接受的范围内。 4) 不要忘记检查函数的返回值 函数的返回值往往表示函数调用是否成功,以此决定下 面的程序流程。如果贸然执行下一步,有可能会出现意想不 到的结果。
delphi程序设计基础教程
第7章 Delphi异常处理与调试 var AChar,AString:ShortString; begin AString:='Welcome to Delphi'; AChar:=Copy(AString,20,1); if AChar<>#0 then // #0是空字符,不是空格 begin if AChar<>'!' then Insert(AChar,AString,20); Exit; end; end;
delphi程序设计基础教程
第7章 Delphi异常处理与调试
5. 类型转换异常
当试图用转换函数把数据从一种形式转换为另一种形式时引发类型 转换异常EConvertError,特别是当把一个字符串转换为数值时引发。下 面程序中的两条执行语句都将引发一个EConvertError异常。 var r1:Real; int:Integer; begin r1:=StrToFloat('$140.48'); int:=StrToInt('1,402'); end;
第7章 Delphi异常处理与调试
第7章 Delphi异常处理与调试
7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 Delphi异常处理 Delphi异常类 Delphi异常处理机制 Delphi调试器 控制程序的运行 断点 监视表达式的值 实验
第7章 Delphi异常处理与调试
7.1 Delphi异常处理
在上述代码中,虽然检查了Copy()的返回值,但如果 Copy()本身调用失败,则程序就执行不到Exit语句。下面改 用异常处理机制来编写这段代码。
delphi程序设计基础教程
第7章 Delphi异常处理与调试 var AChar,Astring:ShortString; begin try AString:='Welcome to Delphi'; AChar:=Copy(Astring,20,1); if AChar<>'!' then Insert(AChar,AString,20); except Exit; end; End; 采用了异常处理机制后,可以先假设程序不可能出错,按正常的顺 序编写代码。当代码在运行过程中出现异常时,将跳转到except部分, 执行Exit语句。 异常处理机制有两种结构:一种是try…except结构,另一种是 try…finally结构,这两种结构在用法上有很大的区别。 delphi程序设计基础教程
比较常见的语法错误是数据类型不匹配,特别是调用RTL、VCL或 Windows的API时容易发生参数不匹配的错误。为了避免这类错误,建 议使用Delphi的在线帮助,找到RTL、VCL或API的声明,仔细对照它们 的参数。不小心输错变量名或命令语句拼写错误也是经常造成编译期错 误的原因。
编译器检查语法错误的功能是可以自定义的。可以使用【Project】 菜单中的【Options】命令打开【Project Options】对话框,然后设置编 译器的语法检查选项。 delphi程序设计基础教程
delphi程序设计基础教程
第7章 Delphi异常处理与调试
表7-2 浮点异常类及其引发条件
异 常 类 EInvalidOp EZeroDivide EOverFlow EUnderFlow 引 发 条 件 处理器碰到一个未定义的指令 试图被零除 浮点上溢 浮点下溢
各种类型的浮点数(Real、Single、Double、 Extended)越界引起同样的溢出异常。 4. 类型匹配异常 当试图用As操作符把一个对象与另一类对象匹 配失败后引发类型匹配异常EInvalidCast。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
异常几乎是不可避免的。过去,在没有异常处理机制的 情况下,程序员不得不小心翼翼地检查每一次函数调用的返 回值,或者通过额外的代码捕获可能的错误。 关键是,通过检查函数的返回值或设置错误陷阱只能捕 获可预见的错误。如果发生没有预见到的错误,或者函数调 用本身就已失败,则程序正常的流程将被打乱。 还有一个问题就是,程序中过多的错误检查代码也破坏 了程序的可读性。事实上,这些代码大都是闲置的,因为程 序中到处发生异常的可能性毕竟不是很大。 使用Object Pascal语言的异常处理机制,就能解决上述 弊端。它既能使程序的安全性得到保证,又不至于使程序代 码过分琐碎。下面先看一段没有采用异常处理机制的代码:
第7章 Delphi异常处理与调试
3. 运行期错误 程序虽然通过了编译,但在运行时失败了,这种错误称 为运行期错误。例如,程序试图打开一个不存在的文件,或 者在运算时出现了被零除。 运行期错误分两种情况,一种是运行时随运行异常环境 或用户输入的错误参数而造成运行错误,这种情况的“错误” 往往无法在交付前通过调试排除,而通常由“异常处理”来 解决;另一种是不随环境和参数变化都会产生的运行错误, 这种情况下,如果不能确认错误发生在什么地方,可以使用 Delphi的内部集成调试器帮助找到错误所在。例如,可以通 过单步执行命令让程序一条语句一条语句地执行,或者通过 一个观察窗口来监视某个变量的变化情况。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
2. 浮点异常 浮点异常是在进行实数操作时产生的,它们都从一个 EMathError类派生,但与整数异常相同,程序运行中引发的 总是它的子类EInvalidOp、EZeroDivide、EOverFlow、 EUnderFlow,见表7-2。 EInvalidOp最常见的引发条件是没有协处理器的机器遇 到一个协处理器指令。由于在默认情况下Delphi总是把浮点 运算编译为协处理器指令,因而在386以下微机上常常会碰 到这个错误。此时只需要在单元的接口部分设置全局编译指 示{$N-},选择利用运行库进行浮点运算,问题就可以解决了。
delphi程序设计基础教程
第7章 Delphi异常处理与调试
由于枚举类型越界而引发一个ERangeError异常。数组 下标越界也会引发一个ERangeError异常,如: var Values:array[1..10] of Integer; I:Integer; begin for I:=1 to 11 do Values[I]:=I; end; ERangeError异常只有当范围检查打开时才会引发。这 可以在代码中包含{$R+}编译指示或设置IDE Option|Project 的Range_Checking Option选择框。注意,Delphi不对长字 符串做范围检查。