第六十三课、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++中存在更好的异常处理方式

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM