# 异常 程序有时会遇到运行阶段错误,导致程序无法正常运行。老式编译器没有实现。有些编译器默认关闭这种特性。以计算两个数的调和平均数为例。`result = 2.0*x*y / (x+y)` 。如果 `y = -x` ,则会导致被零除的错误。新式编译器通过生成一个无穷大的特殊浮点值来处理,`cout`将值显式为`Inf` 、`inf` 或者 `INF` 。其他编译器可能生成被零除的崩溃程序。最好编写在所有系统上都以相同的受控方式运行的代码逻辑。 ## 调用abort() 如果一个参数是另一个参数的负值,可以调用`abort()` 函数来避免崩溃的程序。`abort()` 函数原型位于头文件`cstdlib` (或者`stdlib.h`)中,其典型实现是向标准错误流(即`cerr`)发送消息`abnormal program termination` (程序异常终止),然后终止程序。它还返回一个随实现而异的值,告诉操作系统(如果程序是另一个程序调用的,则告诉父进程),处理失败。`abort()` 是否刷新文件缓冲区取决于实现,如果愿意也可以使用`exit()` ,该函数刷新文件缓冲区,但不显示消息。 ## 返回错误码 比异常终止程序更为灵活的做法是使用函数返回值来指出问题。如将函数改写为以下方式。 ```C++ #include #include bool hmean(double a, double b, double * ans); int main(){ double x, y, z; std::cout<<"Enter two number: "; std::cin>>x>>y; if(hmean(x, y, &z)){ std::cout << z << std::endl; } else{ std::cout << "被零除"; } return 0; } bool hmean(double a, double b, double * ans){ if(a == -b){ *ans = DBL_MAX; return false; } else{ *ans = 2.0*a*b/(a+b); return true; } } ``` ## 异常机制 异常机制是程序运行过程中发生异常情况的一种响应,异常提供了将控制权从程序的一个部分传递到另一个部分的的途径。对异常的处理有三个组成部分。 - 引发异常; - 使用处理程序捕获异常; - 使用try块。 程序在出现问题时将引发异常。thrown语句实际上是跳转,命令程序跳转到另一条语句。thrown关键字表示印发异常,紧随其后的值指出了异常的特征。 程序使用异常处理程序(exception handle)来捕获异常,异常处理程序位于要处理问题的程序中。catch关键字表示捕获异常。处理程序以关键字catch开头,随后是位于括号内的类型声明。 ```C++ #include double hmean(double a, double b); int main(){ double x, y, z; std::cout << "Enter two numbers: "; while(std::cin >> x >> y){ try{ z = hmean(x, y); } catch(const char * s){ std::cout << s << std::endl; std::cout << "Continue enter two numbers: "; continue; } std::cout << z << std::endl; } return 0; } double hmean(double a, double b){ if(a == -b){ throw "bad hmean() arguments: a = -b not allowed"; } return 2.0*a*b/(a+b); } ``` ## exception类 异常主要的目的是为设计容错程序提供语言级支持,即异常使得在程序设计中包含错误处理功能更容易,以免事后采取一些严格的错误处理方式。异常的灵活性和相对性方便程序员在条件允许的情况下在程序中加入错误处理功能。 较新的编译器将异常合并到语言中,为支持该语言exception头文件(之前为exception.h)定义了exception类,程序可以把它作为其他异常类的基类。代码可以引发exception异常,亦可以将exception类作为基类。 ```C++ #include class BadHmean: public std::exception{ public: const char * what() {return "bad arguments to hmean()";} }; ``` 1. stdexcept 异常类 2. bad_alloc异常和new:new会引发bad_alloc异常。 3. 空指针和new。