北京网站建设手机号,网站怎么做描文本,大钟寺网站建设,支付宝微信wordpress这篇文章介绍下 C 的异常处理。
讨论一种最为常见的出现异常的情况#xff0c;即 0 不能作为除数。为此#xff0c;我们将自定义一个除法#xff1a;
#include iostreamusing namespace std;int divide(int a, int b)
{return a / b;
}int main()
{int a 3, b 0…这篇文章介绍下 C 的异常处理。
讨论一种最为常见的出现异常的情况即 0 不能作为除数。为此我们将自定义一个除法
#include iostreamusing namespace std;int divide(int a, int b)
{return a / b;
}int main()
{int a 3, b 0;int res divide(a, b);cout result res;
}事实上这样的代码在我的电脑上运行会卡在终端也没有提示无法运行的报错把 res 直接改成 3/0 就看到正常的报错了
TestDivide.cpp: In function int main():
TestDivide.cpp:14:29: warning: division by zero [-Wdiv-by-zero]14 | cout result 2/0;| ~^~
result 不使用异常机制的处理
abort
尝试在函数内部加入针对除数为0的报错使用 abort()
int divide(int a, int b)
{if(b0){cout cannot divide by 0 endl;abort();}return a / b;
}事实上这次除了打印我加入的一行文字以外程序的运行并没有明显的变化。abort() 的作用是向标准错误流发送消息 abnormal program termination 然后终止程序。它还会返回一个值告诉父进程处理失败。
不知道为什么这里没有终止进程。
返回值处理错误
另一种在 C 里常用的方式是将我们想获取的值作为引用传回来将返回值作为错误的标记。重新设计的 divide 如下
bool divide(int a, int b, int res)
{if(b0){cout cannot divide by zero endl;return false;}else{res a/b;return true; }
}调用我就不写了。
这种方式一定程度上规避掉了系统的异常机制换句话说这是由开发者自己“实现”的异常编译器不会认为这段代码是处理异常的。
使用异常机制的处理
现代C 的异常机制多少借鉴了其他语言的机制即 throw-try-catch-finally 机制即引发异常-捕获异常-处理异常
引发异常
改造 divide 函数使其能够抛出异常
int divide(int a, int b)
{if(b0){throw cannot divide by ZERO!;}return a / b;
}执行 throw 相当于返回了异常因此从某种程度上来说这里的 throw 和 return 的作用差不多。但是不同的是throw并不是把控制权返回给调用程序而是会沿着调用序列后退直到找到能处理异常的 catch 语句为止。
捕获与处理异常
main 函数改写如下
int main()
{int a 3, b 0;int res 0;try{res divide(a, b);}catch (const char *s){cout s endl;}cout res res;
}输出如下
cannot divide by ZERO!
res 0如果引发的异常最终没有与之匹配的类型 catch效果等同于调用 abort() 函数。
使用基于自定义类的异常机制
使用字符串处理异常需要我们编写代码打印异常类型依据面向对象的原则其实写一个类来处理更好。
在头文件中定义一个 bad_divide 类专门用于处理异常其 what() 方法此方法和 C 标准类中的方法在名字上是一致的用于打印异常信息
struct bad_divide
{
private:int a;int b;public:bad_divide(int a, int b) : a(a), b(b){};void what(){cout a divided by b is illegal! endl;}
};同样调用的地方也不再捕捉字符串了而是捕捉这个对象并调用 what() 方法打印异常。
int divide(int a, int b)
{if (b 0){throw bad_divide(a, b);}return a / b;
}int main()
{int a 3, b 0;int res 0;try{res divide(a, b);}catch (bad_divide bd){bd.what();}cout res res;
}