63_C语言异常处理
2018-01-13 本文已影响45人
编程半岛
1. 异常(Exception)的概念
程序在运行过程中可能产生异常,异常是程序运行时可预料的执行分支。
异常与bug的区别:
异常:程序运行时可预料的执行分支
bug是程序中的错误,是不被预期的运行方式
2. 异常处理的方式
- 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 << endl;
}
else
{
cout << "divided by zero ..." << endl;
}
return 0;
}
问题:
(1)divide
函数有3个参数,难以理解其用法
(2)divide
函数调用后必须判断valid
代表的结果
当valid
为true
时,运算结果正常
当valid
为false
时,运算过程出现异常
通过
setjmp()
和longjum()
进行优化
(1)int setjmp(jmp_buf env)
:将当前上下文保存在jmp_buf
结构体中
(2)void longjmp(jmp_buf 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 << endl;
}
else
{
cout << "divided by zero ..." << endl;
}
return 0;
}
缺陷:
setjmp()
和longjmp()
的引入
(1) 必然涉及到使用全局变量
(2) 暴力跳转导致代码可读性降低
(3) 本质还是if...else...
异常处理方式
C语言中的经典异常处理方式会使得程序中逻辑中混入大量的处理异常的代码。
3. 小结
- 程序中不可避免的会发生异常
- 异常时在开发阶段就可以预见的运行时问题
- C语言中通过经典的if...else...方式处理异常
- C++中存在更好的异常处理方式