10.1 概述
10.1.1 什么是异常
- 程序的错误包括:语法错误、逻辑错误和运行异常
- 语法错误:程序书写不符合语言的语法规则,由编译程序发现
- 逻辑错误(语义错误):程序没有完成预期的功能,通过对程序进行静态分析和动态测试来发现
- 运行异常(exception):程序运行错误
- 程序异常往往是没有考虑到程序运行环境的一些特殊情况:
- 关联文件时,文件不存在
- 动态分配空间,内存不足
- 数组下标溢出
- 除以0
- 。。。
- 程序的鲁棒性(或健壮性,robustness):程序在各种极端情况下能正确运行。
- 在程序中,对各种可预见的异常情况进行处理称为异常处理(exception handling)。
10.1.2 异常处理的基本手段
- 就地处理:在发现异常的地方处理异常
- 异地处理:在发现异常的地方不处理异常,把发现的异常交给程序其它地方来处理
10.2 C++异常处理机制
10.2.1 try、throw、catch语句
- 把有可能产生异常的一系列操作(语句或函数调用)构成一个try语句,如果在try语句中出现异常,由throw语句抛出,然后通过catch语句捕获抛出的异常并进行处理。
- 在try语句中,若没有throw异常,则不执行catch语句,而是继续执行try语句块之后的非catch语句
- 在try语句中,若throw异常,则:
- 若有对应catch可以处理,则执行该catch语句
- 若没有对应catch处理,则由函数调用链上的上一层函数中的try语句块的catch来捕获
- 若抛出异常的throw语句不是由try语句中的语句序列调用的,则抛出的异常不会被程序中的catch捕获,将由系统进行标准的异常处理
10.2.2 异常的嵌套处理
- try语句可嵌套:
- 内层的try中发现异常,先交给内层的catch处理;若内层没有对应的catch,交给外层的catch处理
- 若到了函数调用链的最顶端(函数main)也没有能捕获该异常对象的catch语句,则调用系统的terminate函数(默认调用abort函数)进行标准的异常处理。
class Exception{
public:
int divide(int x,int y);
void f();
};
int Exception::divide(int x,int y){
if(y==0){
throw 0;
}
return x/y;
}
voidException::f(){
inta,b;
try{
std::cout<<"请输入两个数:\n";
std::cin>>a>>b;
intr=divide(a,b);
std::cout<<a<<"除以"<<b<<"的商为:"<<r<<std::endl;
}catch(int){
std::cout<<"除数不能为0,请重新输入两个数:\n";
std::cin>>a>>b;
intr=divide(a,b);
std::cout<<a<<"除以"<<b<<"的商为:"<<r<<std::endl;
}
}
int main(){
Exception exception;
try{
exception.f();
}catch(int){
cout<<"请重新运行本程序!\n";
}
return0;
}
请输入两个数:
21 0
除数不能为0,请重新输入两个数:
76 0
请重新运行本程序!
10.3 基于断言的程序调试
- 断言(assertion):是一个逻辑表达式,它描述了程序执行到断言处应满足的条件,如果条件满足则程序继续执行,否则程序执行异常终止。
- C++标准库提供的宏assert可实现断言机制。
- 宏assert要求一个关系/逻辑表示式作为其参数。
- 当assert执行时,如果提供的表达式的值为false,则它会显示相应的表达式、它所在的源文件名以及所在行号等诊断信息,然后调用库函数abort终止程序。
- 当表达式的值为true,程序继续执行。
assert(x==1);//程序执行到该调用处,若x!=1,就会显示“Assertion failed:x==1 , file XXX,line YYY”,并终止程序的运行
- 宏assert只有在宏名NDEBUG没有定义时才有效
10.4 小结
- 导致程序异常的情况可以预料但无法避免,为了提高程序的鲁棒性,程序需要对各种可能导致程序异常的情况进行处理。
- 程序的异常错误有时需要异地处理。
- C++的异常处理机制由try、throw和catch三种语句构成,他们实现了一种结构化的异常处理过程。
- 异常处理可以嵌套。
- 断言机制可以用来发现程序运行中的错误,从而保证程序的正确性。在C++中,断言可以用标准库中的宏assert来实现
https://github.com/zzq1996/ProgrameDesign
参考:《程序设计教程:用C++语言编程》 陈家骏,郑滔