异常处理(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 else 13 { 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\n", divid(1, 0)); 24 } 25 else 26 { 27 printf("Unexpected!!\n"); 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 try 24 { 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 try 37 { 38 func(); 39 } 40 catch(string e) 41 { 42 cout<< e <<endl; 43 } 44 45 return 0; 46 }