异常处理:

 

异常处理的方式:

 

 

示例程序:

 

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 double divide(double a, double b, int* valid)
 7 {
 8     const double delta = 0.000000000000001;
 9     double ret = 0;
10     
11     if( !((-delta < b) && (b < delta)) )
12     {
13         ret = a / b;
14         
15         *valid = 1;
16     }
17     else
18     {
19         *valid = 0;
20     }
21     
22     return ret;
23 }
24 
25 int main(int argc, char *argv[])
26 {   
27     int valid = 0;
28     double r = divide(1, 0, &valid);
29     
30     if( valid )
31     {
32         cout << "r = " << r << endl;
33     }
34     else
35     {
36         cout << "Divided by zero..." << endl;
37     }
38     
39     return 0;
40 }

运行结果如下:

 

 

缺陷:

 

我们需要统一加减乘除的调用方法,将除法改为两个参数,而且还有异常处理的功能。

改进方法:

除法操作异常处理优化:

 1 #include <iostream>
 2 #include <string>
 3 #include <csetjmp>
 4 
 5 using namespace std;
 6 
 7 static jmp_buf env;
 8 
 9 double divide(double a, double b)
10 {
11     const double delta = 0.000000000000001;
12     double ret = 0;
13     
14     if( !((-delta < b) && (b < delta)) )
15     {
16         ret = a / b;
17     }
18     else
19     {
20         longjmp(env, 1);
21     }
22     
23     return ret;
24 }
25 
26 int main(int argc, char *argv[])
27 {   
28     if( setjmp(env) == 0 )
29     {
30         double r = divide(1, 1);
31         
32         cout << "r = " << r << endl;
33     }
34     else
35     {
36         cout << "Divided by zero..." << endl;
37     }
38     
39     return 0;
40 }

程序先执行28行,这是直接执行setjmp,就直接将程序执行上下文保存在env中,然后条件判断为真,然后执行第30行的除法,调用到了divide函数,当除数为0时,这时就会执行到divide的else分支,这时遇到一个longjmp,longjmp根据env恢复程序执行上下文,使得程序回到第28行的状态(也就是从第28行出来),使程序从setjmp返回的地方开始执行,并且将返回值设置为了1,这时第28行的判断就不为真了,于是就执行到了36行的else分支了。

运行结果如下:

这是一种优雅的处理方式,但是理解起来较困难。

缺陷:

 

 

 

小结:

 

posted on 2018-09-05 21:21  周伯通789  阅读(162)  评论(0编辑  收藏  举报