C 學習39 異常處理入門(try和catch)

2022-07-16 09:45:12 字數 2824 閱讀 2824

編譯器能夠保證**的語法是正確的,但是對邏輯錯誤和執行時錯誤卻無能為力,例如除數為 0、記憶體分配失敗、陣列越界等。這些錯誤如果放任不管,系統就會執行預設的操作,終止程式執行,也就是我們常說的程式崩潰(crash)。

優秀的程式設計師能夠從故障中恢復,或者提示使用者發生了什麼;不負責任的程式設計師放任不管,讓程式崩潰。c++提供了異常機制,讓我們能夠捕獲邏輯錯誤和執行時錯誤,並作出進一步的處理。

乙個程式崩潰的例子:

#include using

namespace

std;

intmain()

執行**,在控制台輸出 ch1 的值後程式崩潰。下面我們來分析一下。

at() 是 string 類的乙個成員函式,它會根據下標來返回字串的乙個字元。與「[ ]」不同,at() 會檢查下標是否越界,如果越界就丟擲乙個異常(錯誤);而「[ ]」不做檢查,不管下標是多少都會照常訪問。

上面的**中,下標 100 顯然超出了字串 str 的長度。由於第 6 行**不會檢查下標越界,雖然有邏輯錯誤,但是程式能夠正常執行。而第 8 行**則不同,at() 函式檢測到下標越界會丟擲乙個異常(也就是報錯),這個異常本應由程式設計師處理,但是我們在**中並沒有處理,所以系統只能執行預設的操作,終止程式執行。

在c++中,我們可以捕獲上面的異常,避免程式崩潰。捕獲異常的語法為:

try

catch

(異常型別)

try 和 catch 都是c++中的關鍵字,後跟語句塊,不能省略「」。try 中包含可能會丟擲異常的語句,一旦有異常丟擲就會**獲。從「try」的意思可以看出,它只是「嘗試」捕獲異常,如果沒有異常丟擲,那就什麼也不捕獲。catch 用來處理 try 捕獲到的異常;如果 try 沒有捕獲到異常,就不會執行 catch 中的語句。

修改上面的**,加入捕獲異常的語句:

#include using

namespace

std;

intmain()

catch

(exception e)

trycatch

(exception e)

return0;

}

可以看出,第乙個 try 沒有捕獲到異常,輸出了乙個垃圾值。因為「[ ]」不會檢查下標越界,不會丟擲異常,所以即使有邏輯錯誤,try 什麼也捕獲不到。

第二個 try 捕獲到了異常,並跳轉到 catch,執行 catch 中的語句。需要說明的是,異常一旦丟擲,會立即**獲,而且不會再執行異常點後面的語句。本例中丟擲異常的位置是第 15 行的 at() 函式,它後面的 cout 語句不會再被執行,也就看不到輸出。

所謂丟擲異常,實際上是建立乙份資料,這份資料報含了錯誤資訊,程式設計師可以根據這些資訊來判斷到底出了什麼問題,接下來該怎麼處理。

異常既然是乙份資料,那麼就應該有資料型別。c++規定,異常型別可以是基本型別,也可以是標準庫中類的型別,還可以是自定義類的型別。c++語言本身以及標準庫中的函式丟擲的異常,都是 exception 類或其子類的型別。也就是說,丟擲異常時,會建立乙個 exception 類或其子類的物件。

異常**獲後,會和 catch 所能處理的型別對比,如果正好和 catch 型別匹配,或者是它的子類,那麼就交給當前 catch 塊處理。catch 後面的括號中給出的型別就是它所能處理的異常型別。上面例子中,catch 所能處理的異常型別是 exception,at() 函式丟擲的型別是 out_of_range,out_of_range 是 exception 的子類,所以就交給這個 catch 塊處理。

catch 後面的exception e可以分為兩部分:exception 為異常型別,e 為 exception 類的物件。異常丟擲時,系統會建立 out_of_range 物件,然後將該物件作為「實參」,像函式一樣傳遞給「形參」e,這樣,在 catch 塊中就可以使用 e 了。

其實,乙個 try 後面可以跟多個 catch,形式為:

try

catch

(exception_type_1)

catch

(exception_type_2)

//……

catch

(exception_type_n)

異常**獲時,先和 exception_type_1 作比較,如果異常型別是 exception_type_1 或其子類,那麼執行當前 catch 中的**;如果不是,再和 exception_type_2 作比較……依此類推,直到 exception_type_n。如果最終也沒有找到匹配的型別,就只能交給系統處理,終止程式。

多個 catch 塊的例子:

#include #include 

#include

using

namespace

std;

//自定義錯誤型別

class mytype: public

out_of_range

};int

main()

catch

(mytype)

catch

(out_of_range)

catch

(exception)

return0;

}

try 捕獲到異常後和第乙個 catch 對比,由於此時異常型別為 out_of_range,mytype 是 out_of_range 的子類,所以匹配失敗;繼續向下匹配,發現第二個 catch 合適,匹配結束;第三個 catch 不會被執行。

需要注意的是:catch 後面的括號中僅僅給出了異常型別,而沒有所謂的「形參」,這是合法的。如果在 catch 中不需要使用錯誤資訊,就可以省略「形參」。

C 異常處理入門 try和catch

目錄 開發程式是一項 燒腦 的工作,程式設計師不但要經過長期的知識學習和思維訓練,還要做到一絲不苟,注意每乙個細節和邊界。即使這樣,也不能防止程式出錯。專家指出,長期作息不規律 用腦過度的危害很大,可能會誘發神經衰弱 失眠等疾病。我就是受害者之一,曾被失眠困擾了好幾年,不但入睡困難,還容易早醒。程式...

C 異常處理入門

先看如下 void test02 當你在main 中呼叫test02 時,很明顯會出現如下錯誤 因為除數不能為0,所以執行a b時就會引發錯誤,然後程式就自動停止了。有無錯誤就停止,這到沒什麼,關鍵是這種使用者體驗不是很好,你想一下,當程式執行好好的時候,遇到錯誤,就彈出這麼乙個視窗,然後程式就終止...

try塊和異常處理

try塊和異常處理 c 的異常處理中包括 1 throw表示式,錯誤檢測部分使用這種表示式來說明遇到了不可處理的錯誤。可以說,throw引發了異常條件。2 try塊,錯誤處理部分使用它來處理異常。try語句塊以try關鍵字開始,並以乙個或多個catch子句結束。在try塊中執行的 所丟擲的異常,通常...