📄 028.htm
字号:
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=GB2312"><TITLE>-->DELPHI基础教程-->第十二章 异常处理与程序调试(一)</TITLE>
<META NAME="keywords" CONTENT=" DELPHI基础教程 第十二章 异常处理与程序调试(一)">
<META NAME="description" CONTENT=" - DELPHI基础教程 - 第十二章 异常处理与程序调试(一)">
<style>
<!--
#page {position:absolute; z-index:0; left:0px; top:0px}
.tt3 {font: 9pt/12pt "宋体"}
.tt2 {font: 12pt/15pt "宋体"}
a {text-decoration:none}
a:hover {color: blue;text-decoration:underline}
-->
</style>
</HEAD>
<body text="#000000" aLink=#9900ff link=#006699 vLink=#006699 bgcolor="#FFFFFF" leftmargin="3" topmargin="3" marginheight="3" marginwidth="3">
<TABLE WIDTH="100%" CELLPADDING=10 CELLSPACING=0 BORDER=0>
<TR>
<TD CLASS="tt3" VALIGN="top" width="8%" bgcolor="#e0e0e0"><strong><A HREF="029.htm"><FONT style="FONT-SIZE: 9pt">后一页</font></A><BR>
<A HREF="027.htm"><FONT style="FONT-SIZE: 9pt">前一页</font></A><BR>
<A HREF="index.html"><FONT style="FONT-SIZE: 9pt">回目录</font></A><BR>
<A HREF="../../../../index.htm"><FONT style="FONT-SIZE: 9pt">回首页</font></A><BR>
</strong>
</TD>
<TD class="tt2" bgcolor="#F5F8F8" width="84%"><center><B><FONT style="FONT-SIZE: 16.5pt" COLOR="#FF6666" FACE="楷体_GB2312">第十二章 异常处理与程序调试(一)</FONT></B></center>
<hr color="#EE9B73" size="1" width="94%">
<p> 在应用程序开发中如何检测、处理程序的运行错误是一个很重要的问题。在</font>
Delphi <font face="宋体" lang="ZH-CN">的集成开发环境</font>( IDE )<font
face="宋体" lang="ZH-CN">中提供了一个完善的内置调试器,可以帮助你发现大部分程序错误。但并不是所有的错误都可以被发现,而且当程序涉及到与外设的数据交换或操作外设,如要求用户输入、读写磁盘等时,错误的发生是程序无法控制的,如输入非法字符、磁盘不能读写等。这些情况不仅会导致应用程序异常中止而且可能引起系统的崩溃。针对这些问题,</font>Delphi<font
face="宋体" lang="ZH-CN">同时提供了一套强大的异常处理机制。巧妙地利用它,可以使你的程序更为强健,使用更为友好。</p>
<p> 虽然</font>Delphi<font face="宋体" lang="ZH-CN">为应用程序提供了一套缺省的自动异常处理机制,即当前模块发生错误后退出当前模块并给出错误信息,而并不立即引起应用程序的中止。但当应用程序执行的过程性很强时,仅仅利用这种方法是不够的,而且很容易导致程序执行的不可预测性。 </p>
</font><p align="center">12.1<font face="宋体" lang="ZH-CN"> </font>Delphi<font
face="宋体" lang="ZH-CN">异常处理机制与异常类 </p>
</font><p><font face="宋体" lang="ZH-CN"> </font>Delphi<font face="宋体"
lang="ZH-CN">异常处理机制建立在保护块</font>(Protected Blocks)<font
face="宋体" lang="ZH-CN">的概念上。所谓保护块是用保留字</font>try<font
face="宋体" lang="ZH-CN">和</font>end<font face="宋体" lang="ZH-CN">封装的一段代码。保护块的作用是当应用程序发生错误时自动创建一个相应的异常类</font>(Exception)<font
face="宋体" lang="ZH-CN">。程序可以捕获并处理这个异常类,以确保程序的正常结束以及资源的释放和数据不受破坏。如果程序不进行处理,则系统会自动提供一个消息框。</p>
<p> 异常类是</font>Delphi<font face="宋体" lang="ZH-CN">异常处理机制的核心,也是</font>Delphi<font
face="宋体" lang="ZH-CN">异常处理的主要特色。下面我们对异常类的概念和体系进行详细的介绍。</p>
<p> </font>Delphi<font face="宋体" lang="ZH-CN">提供的所有异常类都是类</font>Exception<font
face="宋体" lang="ZH-CN">的子类。用户也可以从</font>Exception<font
face="宋体" lang="ZH-CN">派生一个自定义的异常类。</p>
<p> </font>Exception<font face="宋体" lang="ZH-CN">类的定义如下,对于不常用的成员没有列出。 </p>
</font><p>{SysUtils <font face="宋体" lang="ZH-CN">单元中}</p>
</font><p>Exception = class(TObject)</p>
<p>private</p>
<p>FMessage: PString;</p>
<p>FHelpContext: Longint;</p>
<p>function GetMessage: String;</p>
<p>procedure SetMessage(const Value: String);</p>
<p>public</p>
<p>constructor Create(const Msg: String);</p>
<p>constructor CreateFmt(const Msg: String; const Args: array of const);. . . </p>
<p>destructor Destroy; override;</p>
<p>property HelpContext: Longint </p>
<p>property Message: String;</p>
<p>property MessagePtr: PString;</p>
<p>end; </p>
<p>Exception<font face="宋体" lang="ZH-CN">的一系列构造函数中最重要的参数是显示的错误信息。而数据成员中最重要的也是可被引用的消息字符串</font>(message<font
face="宋体" lang="ZH-CN">,</font>messagePtr)<font face="宋体" lang="ZH-CN">。</font>
<font face="宋体" lang="ZH-CN">这些信息分别对自定义一个异常类和处理一个异常类有重要作用。</p>
<p> </font>Delphi<font face="宋体" lang="ZH-CN">提供了一个很庞大的异常类体系,这些异常类几乎涉及到编程的各个方面。从大的方面我们可以把异常类分为运行时间库异常、对象异常、部件异常三类。下面我们分别进行介绍。 </p>
</font><p>12.1.1 <font face="宋体" lang="ZH-CN">运行时间库异常类</font>(RTL
Exception) </p>
<font face="宋体" lang="ZH-CN"><p> 运行时间库异常可以分为七类,它们都定义在</font>SysUtils<font
face="宋体" lang="ZH-CN">库单元中。 </p>
</font><p>12.1.1.1 I/O<font face="宋体" lang="ZH-CN">异常 </p>
<p> </font>I/O<font face="宋体" lang="ZH-CN">异常类</font>EInOutError<font
face="宋体" lang="ZH-CN">是在程序运行中试图对文件或外设进行操作失败后产生的,它从</font>Exception<font
face="宋体" lang="ZH-CN">派生后增加了一个公有数据成员</font>ErrorCode<font
face="宋体" lang="ZH-CN">,用于保存所发生错误的代码。这一成员可用于在发生</font>I/O<font
face="宋体" lang="ZH-CN">异常后针对不同情况采取不同的对策。</p>
<p> 当设置编译指示{</font>$I- } <font face="宋体" lang="ZH-CN">时,不产生</font>I/O<font
face="宋体" lang="ZH-CN">异常类而是把错误代码返回到预定义变量</font>IOResult<font
face="宋体" lang="ZH-CN">中。 </p>
</font><p>12.1.1.2 <font face="宋体" lang="ZH-CN">堆异常 </p>
<p> 堆异常是在动态内存分配中产生的,包括两个类</font>EOutOfMemory<font
face="宋体" lang="ZH-CN">和</font>EInvalidPointer<font face="宋体" lang="ZH-CN">。</font></p>
<font face="宋体" lang="ZH-CN"><p>表</font>12.1<font face="宋体" lang="ZH-CN"> 堆异常类及其产生原因</p>
<p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</p>
<p>异常类 引发原因</p>
<p>─────────────────────────────────</p>
</font><p>EOutOfMemory <font face="宋体" lang="ZH-CN">没有足够的空间用于满足所要求的内存分配</p>
</font><p>EInvalidPointer <font face="宋体" lang="ZH-CN">非法指针。一般是由于程序试图去释放一个业已释
放的指针而引起的</font></p>
<p><font face="宋体" lang="ZH-CN">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ </p>
</font><p>12.1.1.3<font face="宋体" lang="ZH-CN"> 整数异常 </p>
<p> 整数异常都是从一个</font>EIntError<font face="宋体" lang="ZH-CN">类派生的,但程序运行中引发的总是它的子类:</font>EDivByZero<font
face="宋体" lang="ZH-CN">,</font>ERangeError<font face="宋体" lang="ZH-CN">,</font>EIntOverFlow<font
face="宋体" lang="ZH-CN">。 </p>
<p> 表</font>12.2<font face="宋体" lang="ZH-CN"> 整数异常及其产生原因</p>
<p>━━━━━━━━━━━━━━━━━━━━━</p>
<p>异常类 引发原因</p>
<p>─────────────────────</p>
</font><p>EDivByZero <font face="宋体" lang="ZH-CN">试图被零除</p>
</font><p>ERangeError <font face="宋体" lang="ZH-CN">整数表达式越界</p>
</font><p>EIntOverFlow <font face="宋体" lang="ZH-CN">整数操作溢出</font></p>
<p><font face="宋体" lang="ZH-CN">━━━━━━━━━━━━━━━━━━━━━━ </p>
<p> </font>ERangeError<font face="宋体" lang="ZH-CN">当一个整数表达式的值超过为一个特定整数类型分配的范围时引发。比如下面一段代码将引发一个</font>ERangeError<font
face="宋体" lang="ZH-CN">异常。 </p>
</font><p>var</p>
<p>SmallNumber: ShortInt;</p>
<p>X , Y: Integer;</p>
<p>begin</p>
<p>X := 100;</p>
<p>Y := 75;</p>
<p>SmallNumber := X * Y;</p>
<p>end;</p>
<font face="宋体" lang="ZH-CN"><p> 特定整数类型包括</font>ShortInt<font
face="宋体" lang="ZH-CN">、</font>Byte<font face="宋体" lang="ZH-CN">以及与整数兼容的枚举类型、布尔类型等。例如: </p>
</font><p>type</p>
<p>THazard = ( Safety , Marginal , Critical , Catastrophic );</p>
<p>var</p>
<p>Haz: THazard;</p>
<p>Item: Integer;</p>
<p>begin</p>
<p>Item:= 4;</p>
<p>Haz:= THazard ( Item );</p>
<p>end; </p>
<p><font face="宋体" lang="ZH-CN">由于枚举数越界而引发一个</font>ERangeError<font
face="宋体" lang="ZH-CN">异常。</p>
<p> 数组元素越界也会引发一个</font>ERangeError<font face="宋体"
lang="ZH-CN">异常,如: </p>
</font><p>var</p>
<p>Values: array[1..10] of Integer;</p>
<p>i: Integer;</p>
<p>begin</p>
<p>for i := 1 to 11 do</p>
<p>Values[i] := i;</p>
<p>end;</p>
<p>ERangeError<font face="宋体" lang="ZH-CN">异常只有当类型检查打开时才会引发。这可以在代码中包含{</font>$R+}
<font face="宋体" lang="ZH-CN">编译指示或设置</font>IDE Option|Project<font
face="宋体" lang="ZH-CN">的</font>Range_Checking Option<font face="宋体" lang="ZH-CN">选择框。</p>
<p> </font>EIntOverFlow<font face="宋体" lang="ZH-CN">异常类在</font>Integer<font
face="宋体" lang="ZH-CN">、</font>Word<font face="宋体" lang="ZH-CN">、</font>Longint<font
face="宋体" lang="ZH-CN">三种整数类型越界时引发。如:</font></p>
<p>var</p>
<p>I : Integer;</p>
<p>a,b,c : Word; </p>
<p>begin</p>
<p>a := 10;</p>
<p>b := 20;</p>
<p>c := 1;</p>
<p>for I := 0 to 100 do</p>
<p>begin</p>
<p>c := a*b*c;</p>
<p>end;</p>
<p>end;</p>
<p><font face="宋体" lang="ZH-CN">引发一个</font>EIntOverFlow<font face="宋体"
lang="ZH-CN">异常。</font></p>
<p>EIntOverFlow<font face="宋体" lang="ZH-CN">异常类只有在编译选择框</font>Option|Project|Over_Flow_Check
Option<font face="宋体" lang="ZH-CN">选中时才产生。当关闭溢出检查,则溢出后变量保留该类整数的最大范围值。</font></p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -