- 1、本文档共23页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C程序设计十异常
C++程序设计
第15章 异常
程序中经常要检查处理各种错误情形,如果用传统的流程控制语句来处理,很容易使程序逻辑混乱。异常(exception)就是一种专门用于检测错误并处理的一种机制,使程序保持逻辑清晰,并改进程序的可靠性。C++语言提供了基本的异常处理机制。本章主要介绍异常的概念、语句、异常类型架构及应用。
可靠的编程应尽可能地、及时地检测到各种异常情形,尽可能在本地处理。尽管有时自己不能处理,也应该向调用方提供详细的出错信息,使调用方能得到充分信息,从而采取合适方式来处理异常。
15.1 异常的概念
异常是什么概念?异常就是在程序运行中发生的难以预料的、不正常的事件而导致偏离正常流程的现象。例如:
访问数组元素的下标越界,在越界时又写入了数据;
用new动态申请内存而返回空指针(可能是因内存不足);
算术运算上溢出或下溢出;
整数除法中除数为0;
调用函数时提供了无效实参,如指针实参为空指针(如用空指针来调用strlen函数);
通过挂空指针或挂空引用来访问对象;
输入整数或浮点数失败;
I/O错误,等等。
上面列出的情形之一如果发生,就可能导致运行错误而终止程序。
发生异常将导致正常流程不能进行,就需要对异常进行处理。那么异常处理是什么概念?异常处理(exception handling)就是在运行时刻对异常进行检测、捕获、提示、传递等过程。如果采用传统的if-else语句来检测处理所有可能发生的异常,很容易导致程序流程混乱,分不清正常流程与异常处理,而且在处理一个异常时往往又引入了新的异常。
假设要设计一个函数,从一个文本文件中读取数据得到一个float矩阵。该文件应存放一个m*n的float矩阵,头两个整数说明其行数m和列数n。你要把它读入并创建一个矩阵对象,以备下一步计算。如果你认为文本文件不会有错,完全按正常编程,不超过10条语句就能完成。如果这个文本文件是别人提供的,而且你的函数将提供给其它人使用,那么你在每一步都要考虑可能出现的错误,此时就可能需要30条语句来处理。例如,可能的出错情形如下:
打开文件出错,文件名可能有误;
读取行数m或者列数n可能出错;
读取每个元素时都可能出错;
矩阵数据可能不完整,也会出错。
如果你用传统方式来判断处理以上这些问题,就会发现正常的流程被淹没在多种异常判断处理之中。此时就需要有一种统一的机制能将正常流程与异常处理分开描述,而保持程序逻辑清晰可读,同时各种异常情形能被集中处理。
C++提供了引发异常语句throw和捕获处理异常语句try-catch。它们构成了一种特殊的流程控制。
用throw引发的每个异常都可以描述为一个对象或一个值。在程序中,每一种异常都可以描述为一种类型,可能是自定义的类,也可能是简单的整数或字符串。在比较完善的编程中,经常用不同的类来描述不同的异常,建立一个异常类型的继承结构,以方便对异常类型的管理和重用。
一个函数中当检测到某种异常发生,但自己往往不知道应该如何处理,此时就应该通知调用方知道发生了什么异常。处理异常的一般方式是:在一个函数中发现一个错误但不能处理,就用throw语句引发一个异常,希望它的(直接或间接)调用方能够捕获并处理这个异常。函数的调用方如果能解决该异常,就可使用try-catch语句来捕获并处理这种异常。如果调用方不能捕获处理该异常,异常就被传递到它自己的调用方,最后到达main函数。
异常的发生、传递与处理的过程与函数调用堆栈相关。如图15.1所示。main函数中调用f函数,f函数再调用g函数。如果g函数执行return就正常返回到f。如果f执行到return就正常返回到main。这是正常流程。
如果g函数在运行时因检测到某种错误而用throw语句引发一个异常,而自己也没有捕获处理,此时该异常就被传递到f的调用方g函数,而且g函数执行终止(注意,不是返回)。对于f来说就是g函数调用发生异常。此时如果f函数没有捕获该异常,那么异常又被传递到它的调用方main函数,此时f函数执行终止。同理,此时如果main也没有捕获该异常,那么程序就必须终止。此时系统可能会跳出一个对话框告知你发生了运行错误。
在发生异常、传递异常的过程中,如果有一个函数用try-catch捕获了该异常,就不会导致程序终止。在运行时刻,一个异常只能被捕获一次。假设f函数捕获了这个异常,那么对于它的调用方main函数来说,就等于没有发生异常。
异常编程的目的是改善程序的可靠性。在大型复杂程序中,完全不发生异常几乎不可能,用传统的if-else语句来检查所有可能的异常情形,也有很大困难。编程正确性总是依赖某些假设成立为前提,异常编程就是要分析识别这些假设不成立的情形,采用面向对象编程技术,建立各种异常类型并形成继承性架构,以处理程序中可能发生的各类异常。
15.2
文档评论(0)