1,C 语言崇尚简洁高效,因此语言本身并没有异常处理的相关语法规则,但是异常处理在 C 语言中 是存在的,我们有必要从 C 语言开始先看一看 C 语言中的异常处理是怎样, 然后对比 C++ 里面的异常处理是怎样;
2,异常的概念:
1,程序在运行过程中可能产生异常;
1,异常是我们在程序开发中必须考虑的一些特殊情况;
2,异常(Exception)与 Bug 的区别:
1,异常是程序运行时可预料的执行分支;
1,例如计算器相关的程序,涉及到除法操作的时候,就应该全面的想想有没有会产生意外的情况,比如除数为 0,这是一种意外情况,但是我们已经预料到这种意外情况,并且这种意外情况在计算器相关的程序里面是不可避免的,因此我们在做开发的时候,就必须有一些代码来处理这样的情况,这些代码就叫做异常处理的代码,而异常是程序运行时可以预料的情况(这就是异常和 Bug 的区别);
2,Bug 是程序中的错误,是不被预期的运行方式;
3,异常和 Bug 的对比:
1,异常:
1,运行时产生除 0 的情况;
2,需要打开的外部文件不存在;
3,数组访问的越界;
2,Bug:
1,使用野指针;
2,堆数组使用结束后未释放;
1,内存泄漏一定是 Bug;
3,选择排序无法处理长度为 0 的数组;
4,异常处理的方式:
1,C 语言经典处理方式:if ... else ...
1,代码示例:
1 void func(...) 2 { 3 if( 判断是否产生异常 ) 4 { 5 // 正常情况代码逻辑; 6 } 7 else 8 { 9 // 异常情况代码逻辑; 10 } 11 }
2,除法操作异常处理编程实验:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 double divide(double a, double b, int* valid) 7 { 8 const double delta = 0.000000000000001; 9 double ret = 0; 10 11 if( !((-delta < b) && (b < delta)) ) 12 { 13 ret = a / b; 14 15 *valid = 1; // 为了处理除数为 0 和本身结果就是 0 之间的区别; 16 } 17 else 18 { 19 *valid = 0; // 异常了; 20 } 21 22 return ret; 23 } 24 25 int main(int argc, char *argv[]) 26 { 27 int valid = 0; 28 double r = divide(1, 0, &valid); 29 30 if( valid ) 31 { 32 cout << "r = " << r << endl; 33 } 34 else 35 { 36 cout << "Divided by zero..." << endl; 37 } 38 39 return 0; 40 }
1,工程上 if 处理正常分支,else 处理异常分支;
2,除法操作需要三个参数,而加减乘法都只要两个参数,这样不优雅;
3,如果第三个参数没有指向合法的对象(NULL),就会出现段错误;
3,缺陷:
1,divide 函数有 3 个参数,难以理解其用法;
1,降低了代码的可读性,后期的维护成本就会增加;
2,改进的方向就是统一除法和加减乘法的调用方式,将三个参数改变为两个参数,并且还有异常处理的代码;
2,divide 函数调用后必须判断 valid 代表的结果;
1,当 valid 为 true 时,运行结果正常;
2,当 valid 为 false 时,运行过程出现异常;
4,通过 setjmp() 和 longjmp() 进行优化:
1,int setjmp(jmp_buf env)
1,将当前上下文保存在 jmp_buf 结构体中;
2,jmp_buf 一般的是全局变量;
2,void longjmp(jmp_b