第六十三课、C语言的异常处理
一、异常处理
1、异常的概念
(1)、程序在运行过程中可能产生异常
(2)、异常(Exception)和Bug的区别
A、异常是程序运行时可预料的执行分支
B、Bug是程序中的错误,是不被预期的运行方式
2、异常(Exception)和Bug的对比
(1)异常
A、运行时产生除0的情况
B、需要打开的外部文件存在
C、数组访问越界
(2)、Bug
A、使用野指针
B、堆数组使用结束后未释放
C、选择排序无法处理长度为0的数组
3、C语言经典处理方式:if....else.....
#include <iostream> using namespace std; double divide(double a, double b, int* valid) { const double delta = 0.000000000000001; double ret = 0; if(!((-delta < b) && (b < delta))) { ret = a / b; *valid = 1; //正常 } else { *valid = 0; //除0错误 } return ret; } int main() { int valid = 0; double r = divide(1, 0, &valid); //当第3个参数为NULL时,还是会出问题 if(valid) { cout << "r = " << r << endl; } else { cout << "Divide by zero..." << endl; } return 0; }
4、缺陷
(1)、divide函数有三个参数,难以理解其用法
(2)、divide函数调用后必须判断valid代表的结果
A、当valid为true时,运算结果正常
B、valid为false时,运行结果出现异常
二、优化方式
1、通过setjmp()和longjmp()进行优化
(1)、int setjmp(jmp_buf env)
A、将当前上下文保存在jmp_buf结构体中
(2)void setjmp(jmp_buf env, int val)
A、从jmp_buf结构体中恢复setjmp()保存上下文
B、最终从setjmp()函数调用点返回,返回值为val
#include <iostream> #include <csetjmp> //for setjmp、longjmp(); using namespace std; static jmp_buf env; //须定义全局的上下文环境 double divide(double a, double b) { const double delta = 0.000000000000001; double ret = 0; if(!((-delta < b) && (b < delta))) { ret = a / b; } else { longjmp(env, 1); //当错误发生时会跳转到setjmp那么的代码 //处,重新执行setjmp并把其的返回值设为1 } return ret; } int main() { if(setjmp(env) == 0) //先保存上下文环境,刚调用时返回值为0 { double r = divide(1, 0); cout << "r = " << r << endl; } else { cout << "Divide by zero..." << endl; } return 0; }
2、缺陷:setjmp()和longjmp()的引入
(1)、必须涉及到使用全局变量
(2)、暴力跳转导致代码可读性降低
(3)、本质还是if...else...的处理方式
三、小结
(1)、程序中不可避免的会发生异常
(2)、异常是在开发阶段就可以预见的运行时问题
(3)、C语言中通过经典的if-else
(4)、C++中存在更好的异常处理方式
本文作者:lgc202
本文链接:https://www.cnblogs.com/gui-lin/p/6379101.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步