C语言中的异常处理
文章目錄
- 1 C語言中的異常處理
- 1.1 異常的概念
- 1.2 C語言中經典的異常處理方式
- 1.3 異常處理方式的優化
1 C語言中的異常處理
1.1 異常的概念
異常的概念:
- 程序在運行的過程中可能產生異常。
- 異常(Exception)與Bug的區別:
- 異常是程序運行時可預料的執行分支。
- Bug是程序中的錯誤,是不被預期的運行方式。
異常(Exception)和Bug的對比:
異常:
- 運行時產生除0的情況
- 需要打開的外部文件不存在
- 數組訪問時越界
Bug:
- 使用野指針
- 堆數組使用結束未釋放
- 選擇排序無法處理長度為0的數組
1.2 C語言中經典的異常處理方式
C語言經典處理方式:if…else…
編程實驗:異常處理代碼
編程實驗:除法操作異常處理
#include <iostream> #include <string>using namespace std;double divide(double a, double b, int* valid) {const double delta = 0.000000000000001;double ret = 0;if( !((-delta < b) && (b < delta)) ){ret = a / b;*valid = 1;}else{*valid = 0;}return ret; }int main(int argc, char *argv[]) { int valid = 0;double r = divide(1, 0, &valid);if( valid ){cout << "r = " << r << endl;}else{cout << "Divided by zero..." << endl;}return 0; }上述異常處理方式的缺陷:
- divide函數有3個參數,難以理解其用法。
- divide函數調用后必須判斷valid代表的結果。
- 當valid為true時,運算結果正常。
- 當valid為false時,運算過程出現異常。
1.3 異常處理方式的優化
通過setjmp()和longjmp()進行優化:
- int setjmp(jmp_buf env):將當前上下文保存在jmp_buf結構體中。
- 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.000000000000001;double ret = 0;if( !((-delta < b) && (b < delta)) ){ret = a / b;}else{longjmp(env, 1);}return ret; }int main(int argc, char *argv[]) { if( setjmp(env) == 0 ){double r = divide(1, 1);cout << "r = " << r << endl;}else{cout << "Divided by zero..." << endl;}return 0; }setjmp()和longjmp()的引入會帶來如下缺陷:
- 必然涉及到使用全局變量。
- 暴力跳轉導致代碼可讀性降低。
- 本質還是if…else…異常處理方式。
C語言中經典異常處理方式會使得程序邏輯中混入大量的處理異常的代碼。正常邏輯代碼和異常處理代碼混合在一起,導致代碼迅速膨脹,難以維護。
參考資料:
總結
- 上一篇: 单例类模板
- 下一篇: 判断一个变量是不是指针