异常处理异常的概念程序在运行过程中可能产生异常异常( Exception ) 与 Bug 的区别* 异常是程序运行时可预料的执行分支* Bug 是程序中的错误,是不被预期的运行方式异常 ( Exception ) 和 Bug 的对比异常* 运行时产生除 0 的情况* 需要打开的外部文件不存在* 数组访问时越界Bug* 使用野指针* 堆数组使用结束后未释放* 选择排序无法处理长度为 0 的数组异常处理的方式C 语言经典处理方式if … else …void func(…){ if( 判断是否产生异常 ) { 正常情况代码逻辑; } else { 异常情况代码逻辑; }}编程实验: 除法操作异常处理#include <iostream>#include <string>using namespace std;double divide(double a, double b, int* valid){ const double delta = 0.00000000000001; double ret = 0; if( !((-delta < b) && (b < delta)) ) { ret = a / b; valid = 1; } else { valid = 0; } return ret;}int main(){ int valid = 0; double r = divide(1, 0, &valid); if( valid ) { cout << “r = " << r << endl; } else { cout << “Divided by zero …” << endl; } return 0;}输出:Divided by zero …缺陷divide 函数有 3 个参数,难以理解其用法divide 函数调用后必须判断 valid 代表的结果当 valid 为 true, 运算结果正常当 valid 为 false, 运算过程中出现异常通过 setjmp() 和 longjmp() 进行优化int setjmp(jmp_buf env)将当前上下文保存在 jum_buf 结构体中void longjmp(jum_env, int val)从 jmp_buf 结构体中恢复 setjmp() 保存的上下文最终从 setjmp 函数调用点返回,返回值为 val编程实验: 除法操作异常处理优化#include <iostream>#include <string>#include <csetjmp>using namespace std;static jmp_buf env;double divide(double a, double b){ const double delta = 0.00000000000001; double ret = 0; if( !((-delta < b) && (b < delta)) ) { ret = a / b; } else { longjmp(env, 1); } return ret;}int main(){ if( setjmp(env) == 0 ) { double r = divide(1, 0); cout << “r = " << r << endl; } else { cout << “Divided by zero …” << endl; } return 0;}输出:Divided by zero …缺陷setjmp() 和 longjmp() 的引入必然涉及到使用全局变量暴力跳转导致代码可读性降低本质还是 if …else … 异常处理方式破坏了结构化程序设计的特性:顺序执行、选择执行、循环执行。C 语言中的经典异常处理方式会使得程序逻辑中混入大量的处理异常的代码正常逻辑代码和异常处理代码混合在遗弃,导致代码迅速膨胀,难以维护。。。实例分析异常处理代码分析#include <iostream>#include <string>using namespace std;#define SUCCESS 0 #define INVALID_POINTER -1#define INVALID_LENGTH -2#define INVALID_PARAMETER -3int MemSet(void dest, unsigned int length, unsigned char v){ if( dest == NULL ) { return INVALID_POINTER; } if( length < 4 ) { return INVALID_LENGTH; } if( (v < 0) || (v > 9) ) { return INVALID_PARAMETER; } unsigned char p = (unsigned char*)dest; for(int i=0; i<length; i++) { p[i] = v; } return SUCCESS;}int main(int argc, char *argv[]){ int ai[5]; int ret = MemSet(ai, sizeof(ai), 0); if( ret == SUCCESS ) { } else if( ret == INVALID_POINTER ) { } else if( ret == INVALID_LENGTH ) { } else if( ret == INVALID_PARAMETER ) { } return ret;}问题:阅读体较差,无法快速判断出哪一部分是正常逻辑代码,哪一部分是异常逻辑代码小结程序中不可避免的会发生异常异常是在开发阶段就可以遇见的运行时问题C 语言中通过 if … else … 方式处理异常C++ 中存在更好的异常处理方式以上内容参考狄泰软件学院系列课程,请大家保护原创