最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++異常處理入門(try和catch)

 更新時間:2021年08月09日 09:20:31   投稿:zx  
C++ 提供了異常機制,讓我們能夠捕獲運行時錯誤,本文就詳細(xì)的介紹了C++異常處理入門,具有一定的參考價值,感興趣的小伙伴們可以參考一下

開發(fā)程序是一項“燒腦”的工作,程序員不但要經(jīng)過長期的知識學(xué)習(xí)和思維訓(xùn)練,還要做到一絲不茍,注意每一個細(xì)節(jié)和邊界。即使這樣,也不能防止程序出錯。

專家指出,長期作息不規(guī)律 + 用腦過度的危害很大,可能會誘發(fā)神經(jīng)衰弱、失眠等疾病。我就是受害者之一,曾被失眠困擾了好幾年,不但入睡困難,還容易早醒。程序員要注意勞逸結(jié)合,多去健身房,多跑步,多打球,多陪女朋友旅游等,千萬不要熬夜,以為深夜寫代碼效率高,這樣會透支年輕的身體。

程序的錯誤大致可以分為三種,分別是語法錯誤、邏輯錯誤和運行時錯誤:

1) 語法錯誤在編譯和鏈接階段就能發(fā)現(xiàn),只有 100% 符合語法規(guī)則的代碼才能生成可執(zhí)行程序。語法錯誤是最容易發(fā)現(xiàn)、最容易定位、最容易排除的錯誤,程序員最不需要擔(dān)心的就是這種錯誤。

2) 邏輯錯誤是說我們編寫的代碼思路有問題,不能夠達(dá)到最終的目標(biāo),這種錯誤可以通過調(diào)試來解決。

3) 運行時錯誤是指程序在運行期間發(fā)生的錯誤,例如除數(shù)為 0、內(nèi)存分配失敗、數(shù)組越界、文件不存在等。C++ 異常(Exception)機制就是為解決運行時錯誤而引入的。

運行時錯誤如果放任不管,系統(tǒng)就會執(zhí)行默認(rèn)的操作,終止程序運行,也就是我們常說的程序崩潰(Crash)。C++ 提供了異常(Exception)機制,讓我們能夠捕獲運行時錯誤,給程序一次“起死回生”的機會,或者至少告訴用戶發(fā)生了什么再終止程序。

【例1】一個發(fā)生運行時錯誤的程序:

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str = "http://c.biancheng.net";
    char ch1 = str[100];  //下標(biāo)越界,ch1為垃圾值
    cout<<ch1<<endl;
    char ch2 = str.at(100);  //下標(biāo)越界,拋出異常
    cout<<ch2<<endl;
    return 0;
}

運行代碼,在控制臺輸出 ch1 的值后程序崩潰。下面我們來分析一下原因。

at() 是 string 類的一個成員函數(shù),它會根據(jù)下標(biāo)來返回字符串的一個字符。與[ ]不同,at() 會檢查下標(biāo)是否越界,如果越界就拋出一個異常;而[ ]不做檢查,不管下標(biāo)是多少都會照常訪問。

所謂拋出異常,就是報告一個運行時錯誤,程序員可以根據(jù)錯誤信息來進(jìn)一步處理。

上面的代碼中,下標(biāo) 100 顯然超出了字符串 str 的長度。由于第 6 行代碼不會檢查下標(biāo)越界,雖然有邏輯錯誤,但是程序能夠正常運行。而第 8 行代碼則不同,at() 函數(shù)檢測到下標(biāo)越界會拋出一個異常,這個異常可以由程序員處理,但是我們在代碼中并沒有處理,所以系統(tǒng)只能執(zhí)行默認(rèn)的操作,也即終止程序執(zhí)行。

捕獲異常

我們可以借助 C++ 異常機制來捕獲上面的異常,避免程序崩潰。捕獲異常的語法為:

try{
    // 可能拋出異常的語句
}catch(exceptionType variable){
    // 處理異常的語句
}

try和catch都是 C++ 中的關(guān)鍵字,后跟語句塊,不能省略{ }。try 中包含可能會拋出異常的語句,一旦有異常拋出就會被后面的 catch 捕獲。從 try 的意思可以看出,它只是“檢測”語句塊有沒有異常,如果沒有發(fā)生異常,它就“檢測”不到。catch 是“抓住”的意思,用來捕獲并處理 try 檢測到的異常;如果 try 語句塊沒有檢測到異常(沒有異常拋出),那么就不會執(zhí)行 catch 中的語句。

這就好比,catch 告訴 try:你去檢測一下程序有沒有錯誤,有錯誤的話就告訴我,我來處理,沒有的話就不要理我!

catch 關(guān)鍵字后面的exceptionType variable指明了當(dāng)前 catch 可以處理的異常類型,以及具體的出錯信息。我們稍后再對異常類型展開講解,當(dāng)務(wù)之急是演示一下 try-catch 的用法,先讓讀者有一個整體上的認(rèn)識。

【例2】修改上面的代碼,加入捕獲異常的語句:

#include <iostream>
#include <string>
#include <exception>
using namespace std;
int main(){
    string str = "http://c.biancheng.net";
  
    try{
        char ch1 = str[100];
        cout<<ch1<<endl;
    }catch(exception e){
        cout<<"[1]out of bound!"<<endl;
    }
    try{
        char ch2 = str.at(100);
        cout<<ch2<<endl;
    }catch(exception &e){  //exception類位于<exception>頭文件中
        cout<<"[2]out of bound!"<<endl;
    }
    return 0;
}

運行結(jié)果:
(
[2]out of bound!

可以看出,第一個 try 沒有捕獲到異常,輸出了一個沒有意義的字符(垃圾值)。因為[ ]不會檢查下標(biāo)越界,不會拋出異常,所以即使有錯誤,try 也檢測不到。換句話說,發(fā)生異常時必須將異常明確地拋出,try 才能檢測到;如果不拋出來,即使有異常 try 也檢測不到。所謂拋出異常,就是明確地告訴程序發(fā)生了什么錯誤。

第二個 try 檢測到了異常,并交給 catch 處理,執(zhí)行 catch 中的語句。需要說明的是,異常一旦拋出,會立刻被 try 檢測到,并且不會再執(zhí)行異常點(異常發(fā)生位置)后面的語句。本例中拋出異常的位置是第 17 行的 at() 函數(shù),它后面的 cout 語句就不會再被執(zhí)行,所以看不到它的輸出。

說得直接一點,檢測到異常后程序的執(zhí)行流會發(fā)生跳轉(zhuǎn),從異常點跳轉(zhuǎn)到 catch 所在的位置,位于異常點之后的、并且在當(dāng)前 try 塊內(nèi)的語句就都不會再執(zhí)行了;即使 catch 語句成功地處理了錯誤,程序的執(zhí)行流也不會再回退到異常點,所以這些語句永遠(yuǎn)都沒有執(zhí)行的機會了。本例中,第 18 行代碼就是被跳過的代碼。

執(zhí)行完 catch 塊所包含的代碼后,程序會繼續(xù)執(zhí)行 catch 塊后面的代碼,就恢復(fù)了正常的執(zhí)行流。

為了演示「不明確地拋出異常就檢測不到異?!?,大家不妨將第 10 行代碼改為char ch1 = str[100000000];,訪問第 100 個字符可能不會發(fā)生異常,但是訪問第 1 億個字符肯定會發(fā)生異常了,這個異常就是內(nèi)存訪問錯誤。運行更改后的程序,會發(fā)現(xiàn)第 10 行代碼產(chǎn)生了異常,導(dǎo)致程序崩潰了,這說明 try-catch 并沒有捕獲到這個異常。

關(guān)于「如何拋出異?!?,我們將在下節(jié)講解,這里重點是讓大家明白異常的處理流程:

拋出(Throw)--> 檢測(Try) --> 捕獲(Catch)

發(fā)生異常的位置

異??梢园l(fā)生在當(dāng)前的 try 塊中,也可以發(fā)生在 try 塊所調(diào)用的某個函數(shù)中,或者是所調(diào)用的函數(shù)又調(diào)用了另外的一個函數(shù),這個另外的函數(shù)中發(fā)生了異常。這些異常,都可以被 try 檢測到。

1) 下面的例子演示了 try 塊中直接發(fā)生的異常:

#include <iostream>
#include <string>
#include <exception>
using namespace std;
int main(){
    try{
        throw "Unknown Exception";  //拋出異常
        cout<<"This statement will not be executed."<<endl;
    }catch(const char* &e){
        cout<<e<<endl;
    }
    return 0;
}

運行結(jié)果:
Unknown Exception

throw關(guān)鍵字用來拋出一個異常,這個異常會被 try 檢測到,進(jìn)而被 catch 捕獲。關(guān)于 throw 的用法,我們將在下節(jié)深入講解,這里大家只需要知道,在 try 塊中直接拋出的異常會被 try 檢測到。

2) 下面的例子演示了 try 塊中調(diào)用的某個函數(shù)中發(fā)生了異常:

#include <iostream>
#include <string>
#include <exception>
using namespace std;
void func(){
    throw "Unknown Exception";  //拋出異常
    cout<<"[1]This statement will not be executed."<<endl;
}
int main(){
    try{
        func();
        cout<<"[2]This statement will not be executed."<<endl;
    }catch(const char* &e){
        cout<<e<<endl;
    }
    return 0;
}

運行結(jié)果:
Unknown Exception

func() 在 try 塊中被調(diào)用,它拋出的異常會被 try 檢測到,進(jìn)而被 catch 捕獲。從運行結(jié)果可以看出,func() 中的 cout 和 try 中的 cout 都沒有被執(zhí)行。

3) try 塊中調(diào)用了某個函數(shù),該函數(shù)又調(diào)用了另外的一個函數(shù),這個另外的函數(shù)拋出了異常:

#include <iostream>
#include <string>
#include <exception>
using namespace std;
void func_inner(){
    throw "Unknown Exception";  //拋出異常
    cout<<"[1]This statement will not be executed."<<endl;
}
void func_outer(){
    func_inner();
    cout<<"[2]This statement will not be executed."<<endl;
}
int main(){
    try{
        func_outer();
        cout<<"[3]This statement will not be executed."<<endl;
    }catch(const char* &e){
        cout<<e<<endl;
    }
    return 0;
}

運行結(jié)果:
Unknown Exception

發(fā)生異常后,程序的執(zhí)行流會沿著函數(shù)的調(diào)用鏈往前回退,直到遇見 try 才停止。在這個回退過程中,調(diào)用鏈中剩下的代碼(所有函數(shù)中未被執(zhí)行的代碼)都會被跳過,沒有執(zhí)行的機會了。

到此這篇關(guān)于C++異常處理入門(try和catch)的文章就介紹到這了,更多相關(guān)C++異常處理 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)靜態(tài)鏈表的方法

    C語言實現(xiàn)靜態(tài)鏈表的方法

    分享一段代碼,一個靜態(tài)鏈表的C語言實現(xiàn),其中包含著一種簡單的內(nèi)存管理策略:固定大小的鏈?zhǔn)焦芾怼?/div> 2013-03-03
  • 深入理解C/C++混合編程

    深入理解C/C++混合編程

    本篇文章是對C/C++混合編程進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 示例詳解C++中的各種鎖

    示例詳解C++中的各種鎖

    C++中常見的鎖包括互斥鎖、遞歸互斥鎖、讀寫鎖、定時互斥鎖、遞歸定時互斥鎖、自旋鎖和條件變量,互斥鎖用于防止多線程同時訪問共享資源,遞歸互斥鎖允許同一線程多次獲取鎖,讀寫鎖區(qū)分讀寫操作,提高并發(fā)性
    2024-11-11
  • 利用C語言實現(xiàn)猜數(shù)字小游戲

    利用C語言實現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了利用C語言實現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Windows下VScode實現(xiàn)簡單回聲服務(wù)的方法

    Windows下VScode實現(xiàn)簡單回聲服務(wù)的方法

    回聲服務(wù)端可以將客戶端傳來的信息,再原封不動地發(fā)送給客戶端,因而得名 epoch 服務(wù)。接下來通過本文給大家介紹Windows下VScode實現(xiàn)簡單回聲服務(wù)的方法,感興趣的朋友一起看看吧
    2021-08-08
  • 基于QT繪制一個漂亮的預(yù)警儀表

    基于QT繪制一個漂亮的預(yù)警儀表

    這篇文章主要為大家詳細(xì)介紹了如何基于QT繪制一個漂亮的預(yù)警儀表,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的可以了解一下
    2023-04-04
  • QT使用QChart繪制面積圖

    QT使用QChart繪制面積圖

    在Qt中使用QChart類可以快速繪制一個圖表出來,比如折線圖、餅圖、柱狀圖等,本文就來為大家介紹一下如何利用QChart繪制簡單的面積圖吧
    2024-11-11
  • C++實現(xiàn)雷霆戰(zhàn)機可視化小游戲

    C++實現(xiàn)雷霆戰(zhàn)機可視化小游戲

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)雷霆戰(zhàn)機可視化小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++?指針和對象成員訪問的區(qū)別:`.`?與?`->`?的使用小結(jié)

    C++?指針和對象成員訪問的區(qū)別:`.`?與?`->`?的使用小結(jié)

    在學(xué)習(xí)?C++?時,常常會遇到訪問對象成員的兩種符號:.?和?->,這兩個符號看似簡單,但它們的正確使用卻需要理解指針和對象的本質(zhì)差異,本文介紹C++?指針和對象成員訪問的區(qū)別:`.`?與?`->`?的使用指南,感興趣的朋友一起看看吧
    2024-12-12
  • C++實現(xiàn)學(xué)生信息管理系統(tǒng)(Map實現(xiàn))

    C++實現(xiàn)學(xué)生信息管理系統(tǒng)(Map實現(xiàn))

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評論

隆德县| 赞皇县| 信宜市| 永顺县| 金沙县| 石楼县| 河曲县| 新疆| 光泽县| 滦平县| 成武县| 进贤县| 绿春县| 泾源县| 遵义市| 互助| 饶阳县| 崇州市| 正镶白旗| 湘潭市| 榆社县| 汕头市| 双江| 章丘市| 延吉市| 石首市| 文化| 苍溪县| 大名县| 即墨市| 鄂尔多斯市| 堆龙德庆县| 湄潭县| 渑池县| 綦江县| 上思县| 望谟县| 滨州市| 三原县| 九江市| 赤城县|