异常处理(C语言)
if () { ... } else { ... }
setjmp和longjmp
1 #include <stdio.h> 2 #include <setjmp.h> 3 4 jmp_buf env = {0}; 5 6 int divid(int a, int b) 7 { 8 if(b == 0) 9 {10 longjmp(env, 1); //2. 恢复保存的上下文,并设置setjmp的返回值(第二个参数)11 }12 else13 {14 return a / b;15 }16 }17 18 int main()19 {20 if(setjmp(env) == 0) //1. 保存当前上下文,返回为0;21 //3. 调用longjmp后,返回此处,返回值为longjmp设置的返回值22 {23 printf("divid(1, 0) = %d", divid(1, 0));24 }25 else26 {27 printf("Unexpected!!");28 }29 30 return 0; 31 }
异常处理(C++语言)
异常的抛出和处理分开,更合理、灵活
try { ... } catch { ... }
使用throw关键字抛出异常,抛出的异常可以是任何类型,基础类型、类类型以及自定义类型都可以
异常抛出后,会沿着函数调用的顺序向上依次寻找捕捉的地方,如果找不到,程序终止;如果找到(匹配到catch),进入catch进行处理,程序不终止
一个try可以接续多个catch,catch的匹配规则如下:
每个异常只能被一个catch分支处理
匹配的过程从上至下依次匹配
匹配的规则类似函数调用的过程,但是不进行隐式类型转换,严格参数匹配
抛出的异常会有用于初始化catch中的参数
基类可以匹配子类的异常
不一定要使用C++库中提供的异常,可以使用自定义的异常
一般使用可变参数作为最后一个catch分支,做楼底处理
try { ... } catch { ... }可以嵌套,工程意义是对异常进行重新解释,做兼容处理
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 void func() //嵌套,对异常进行重新封装解释 7 { 8 try 9 {10 throw 2;11 }12 catch(int i)13 {14 if(i == 2)15 {16 throw string("error no 2");17 }18 }19 }20 21 int main()22 {23 try24 {25 throw 1;26 }27 catch(int e)28 {29 cout<< "catch(int e)" << endl;30 }31 catch(...)32 {33 cout<< "catch(...)" <<endl;34 }35 36 try37 {38 func();39 }40 catch(string e)41 {42 cout<< e <<endl;43 }44 45 return 0; 46 }