中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言異常處理的方式

發布時間:2020-09-14 00:38:00 來源:網絡 閱讀:4155 作者:小溢 欄目:編程語言



1、語言本身沒有異常處理的原則。


一、異常的概念:


1、程序在運行過程中可能產生異常。


2、異常(Exception)與Bug的區別


@1:異常是程序運行時可預料的執行分支。是我們在程序開發時要考慮的一些特殊情況

@2:Bug是程序中的錯誤,是不可被預期的運行方式




二、異常(Exception)和Bug的對比


1、異常的例子:


(1)運行時產生除0的情況


(2)需要打開的外部文件不存在


(3)數組訪問越界


2、bug的例子:


(1)使用了野指針


(2)堆數組使用結束后未釋放


(3)選擇排序無法處理長度為0的數組



三、C語言經典處理異常的方式:if...else...


1、

void func(...)

{

if (判斷是否產生異常)

{

正常情況的代碼邏輯;

}

else

{

異常情況代碼邏輯;

}

}


四、編程實踐一下異常處理


1、在C語言中,除法操作異常處理(除數為0的情況),不是完美的方法


例:


#include <stdio.h>


/*

* C語言中對除數為0情況下的異常處理方法,不是完美的方法

*

*/


static double divide(double a, double b, int *valid) //用valid表示異常是否發生,1為沒發生、0為發生

{

const double delta = 0.000000000001;

double ret = 0;

if (!((-b < delta) && (b < delta)))

{

*valid = 1;

ret = a / b;

}

else

{

*valid = 0;

}

return ret;

}



inline static int char_to_num(const char c)

{

return (c - 48);

}


int main(int argc, char *argv[])

{

int valid = 0;

double r = 0;


#if 0

if (2 == argc)

{

printf("argc = %d. argv[1][0] = %d.\n", argc, argv[1][0]);

}

#endif

r = divide(char_to_num(argv[1][0]), char_to_num(argv[1][1]), &valid);

if (valid)

{

printf("r = %f.\n", r);

}

else 

{

printf("Divide operator error, by zero.\n");

}

// printf("char_to_num(%c) = %d.\n", '1', char_to_num('9') );

return 0;

}


2、上面例子處理除數為0的異常情況的缺陷:


(1)divide函數有三個參數,難以理解其用法


(2)divide函數調用后必須判斷valid代表的結果


@1:當vaild為true時,運算結果正常

@2:當vaild為false時,運算過程出現異常

3、所以我們要將上面的divide函數的缺陷彌補起來,使其只有兩個參數,用起來方便。


(1)C語言提供了兩個函數:setjmp()和longjmp()進行優化。但是這兩個函數不要隨意的調用,因為這兩個函數簡單出爆,將破壞結構化程序設計的特性

在<csetjmp>頭文件中


@1:

int setjmp(jmp_buf env)


:將當前上下文保存在jmp_buf結構體中


@2:

void longjmp(jmp_buf env, int val)


:從jmp_buf結構體中恢復setjmp()保存的上下文


:最終從setjmp函數調用點返回,返回值為val


(2)利用setjmp()和longjmp()函數來節省divide函數對除數為0情況時的異常處理,但這個方法也不好。


例:


#include <stdio.h>

#include <setjmp.h>


/*

* C語言中對除數為0情況下的異常處理方法,這個方法也不好,還不如用三個參數的divide解決

*

*/


static jmp_buf jmpbuff;


static double divide(double a, double b) //用valid表示異常是否發生,1為沒發生、0為發生

{

const double delta = 0.000000000001;

double ret = 0;

if (!((-b < delta) && (b < delta)))

{

ret = a / b;

}

else

{

longjmp(jmpbuff, 1); //代碼如果執行到這里,調用這個函數時,會跳轉到setjmp這個函數調用的位置,并且這時setjmp函數的返回值為這個longjmp函數的第二個參數值

}

return ret;

}



inline static int char_to_num(const char c)

{

return (c - 48);

}



int main(int argc, char *argv[])

{


#if 0

if (2 == argc)

{

printf("argc = %d. argv[1][0] = %d.\n", argc, argv[1][0]);

}

#endif

if (setjmp(jmpbuff) == 0)

{

printf("num = %f.\n", divide((double)char_to_num(argv[1][0]), (double)char_to_num(argv[1][1])));

}

else 

{

printf("Divide operator error, by zero.\n");

}

// printf("char_to_num(%c) = %d.\n", '1', char_to_num('9') );

return 0;

}



(3)使用setjmp()和longjmp()的缺陷


@1:必然涉及到使用一個jmp_buf類型的全局變量


@2:暴力跳轉導致代碼可讀性降低。


@3:本質還是if...else...異常處理方式,C語言中處理異常方式的經典方法。


(3)C語言中的經典異常處理方式會使得程序邏輯中混入大量的處理異常的代碼, 正常邏輯代碼和異常處理代碼混合在一起,導致代碼迅速膨脹,難以維護。



4、C++中有沒有更好的異常處理方式呢?


(1)答案是有的,C++語言中已經將直接將異常的概念內置于語法當中了。可以通過關鍵字就可以看出來哪些代碼是處理正常功能的代碼,哪些代碼是進行異常處理的代碼。




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南江县| 池州市| 巨野县| 内丘县| 德格县| 从化市| 南康市| 阿鲁科尔沁旗| 桃园县| 海晏县| 蓝田县| 壶关县| 沂水县| 岳普湖县| 罗平县| 夏邑县| 凉城县| 纳雍县| 乌恰县| 丰宁| 伊宁县| 海原县| 乌海市| 新绛县| 德州市| 广德县| 寿阳县| 云龙县| 时尚| 镇赉县| 庐江县| 潜山县| 玉田县| 南木林县| 元氏县| 武山县| 耒阳市| 邯郸县| 遂溪县| 家居| 宜兴市|