兩學(xué)一做網(wǎng)站無法做題鞏義網(wǎng)站優(yōu)化公司
目錄
錯誤處理
異常處理
異常傳播
異常規(guī)劃
標(biāo)準(zhǔn)異常
自定異常
錯誤處理
-
在C語言中,錯誤通常通過函數(shù)的返回值來表示。
-
錯誤返回值
- 對于能返回特殊值(如NULL或負(fù)值)的函數(shù),在調(diào)用時檢查這些值來處理錯誤。
-
#include <stdio.h> #include <stdlib.h>#define DIV_RET_SUCCESS 1 #define DIV_RET_FAILED 0//C語言中通過函數(shù)返回值來判斷執(zhí)行成功與否 int myDiv(int num1, int num2, int* nRet) {if (num2 == 0){*nRet - 0;return DIV_RET_FAILED;}*nRet = num1 / num2;return DIV_RET_SUCCESS; }int main() {int ret = 0;if (myDiv(10, 2, &ret) == DIV_RET_SUCCESS){printf("%d \r\n", ret);}return 0; }
-
錯誤碼全局變量
- 如 errno???,這是一個全局變量,很多標(biāo)準(zhǔn)庫函數(shù)在出錯時會設(shè)置這個變量為相應(yīng)的錯誤碼。
-
#pragma warning(disable:4996) #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h>int main() {FILE* pFile = NULL;pFile = fopen("0xCC.txt", "r");if (pFile == NULL){printf("ErrorCode -> %d \r\n", errno);printf("ErrorMesg -> %s \r\n", strerror(errno));perror("fopen");}return 0; }
-
宏定義
- 通過宏定義可以創(chuàng)建簡單的錯誤處理代碼塊,這個方法提供了一種快速插入常用錯誤處理程序代碼的方式。
-
#include <stdio.h> #include <stdlib.h> #define HANDLE_ERROR(msg) \do { \perror(msg); \exit(EXIT_FAILURE); \} while(0) int main() {FILE *fp = fopen("file.txt", "r");if (!fp) {HANDLE_ERROR("Error opening file");}// 其余代碼...fclose(fp);return 0; }
異常處理
-
throw:當(dāng)問題發(fā)生時,程序會拋出一個異常。這是通過 throw?? 關(guān)鍵字完成的,后面跟著要拋出的異常對象。
throw ErrorCode throw "Erroe"
-
try:try?? 塊內(nèi)的代碼是可能產(chǎn)生異常的代碼,當(dāng)其中的代碼拋出一個異常時,執(zhí)行流會跳轉(zhuǎn)到匹配的 catch?? 塊。
-
catch:catch?? 塊會捕獲異常,并包含如何處理這些異常的代碼。
try {//可能拋出異常的代碼 } catch(ExceptionType var) //根據(jù)異常類型捕獲 {//處理匹配異常類型 } catch(ExceptionType var) //根據(jù)異常類型捕獲 {//處理匹配異常類型 }
-
示例代碼
#include <iostream>int AllocMem() {//可能會拋出異常的代碼放在try語句塊內(nèi)try{//throw 'A';long long* p = new long long[0xFFFFFFF];//thorw bad_allocation}catch (int exception){std::cout << exception << std::endl;}catch (char exception){std::cout << exception << std::endl;}catch (std::exception exception){std::cout << exception.what() << std::endl;}}int main() {AllocMem();return 0; }
異常傳播
-
C++異常傳播(Exception Propagation)是指在程序中如果一個函數(shù)內(nèi)發(fā)生了異常,而該異常沒有在該函數(shù)內(nèi)得到處理,則該異常會被傳遞到函數(shù)調(diào)用者處,如果調(diào)用者也不處理,則繼續(xù)傳遞,這樣一直到最頂層調(diào)用者。如果最頂層調(diào)用者也沒有處理異常,則程序可能崩潰。
- 如果try???塊內(nèi)的代碼拋出了異常,控制流會跳到第一個匹配的catch???塊。
- 如果在當(dāng)前函數(shù)中沒有匹配的catch???塊,異常會被傳遞給調(diào)用該函數(shù)的函數(shù),并在那里尋找匹配的catch???塊。
- 如果在任一函數(shù)中都找不到匹配的catch??塊,程序?qū)⒄{(diào)用terminate()??結(jié)束程序。
#include <iostream>void Fun3() {throw 0xCC; }void Fun2() {try{Fun3();}catch (char exception){std::cout << exception << std::endl;}}void Fun1() {try{Fun2();}catch (float exception){std::cout << "Fun1 Exception" << std::endl;}}int main() {try{Fun1();}catch (...){std::cout << "Main Exception" << std::endl;}return 0; }
異常規(guī)劃
- 異常規(guī)范(exception specification)是C++中的一種功能,它允許開發(fā)者指明一個函數(shù)可能拋出哪些異常。
- 自從C++11起,異常規(guī)范已經(jīng)不再被推薦使用,取而代之的是noexcept關(guān)鍵字。
- ?void someFunction() throw(int, char); ??// 只能拋出int型和char型異常
- ?void someFunction() noexcept; ??// 不會拋出異常
-
#include <iostream> #include <vector>//該函數(shù)不會拋出任何異常 void Fun1() throw() {}void Fun2() noexcept {}void Fun3() throw(int) {}void Fun4() throw(char) {}void Fun5() throw(char, int) {}int main() {try{Fun3();}catch (int exception){std::cout << exception << std::endl;}try{Fun4();}catch (char exception){std::cout << exception << std::endl;}try{Fun5();}catch (char exception){std::cout << exception << std::endl;}catch (int exception){std::cout << exception << std::endl;}return 0; }
標(biāo)準(zhǔn)異常
- ?std::exception?? 是各種標(biāo)準(zhǔn)異常類的基礎(chǔ),提供了一個異常層次結(jié)構(gòu)。
-
?std::logic_error??
- 邏輯錯誤表示程序的邏輯不當(dāng)導(dǎo)致的問題,這通常是可以預(yù)防的錯誤。
- ?std::domain_error??: 當(dāng)一個數(shù)學(xué)函數(shù)接收到一個不在其定義域內(nèi)的參數(shù)時拋出。
- ?std::invalid_argument??: 當(dāng)傳遞給函數(shù)的參數(shù)無效時拋出。
- ?std::length_error??: 當(dāng)創(chuàng)建過大的 std::string?? 或者 std::vector?? 時拋出。
- ?std::out_of_range??: 當(dāng)通過 at?? 訪問 std::vector?? 或 std::string?? 而下標(biāo)超出范圍時拋出。
-
std::runtime_error??
- 運(yùn)行時錯誤,表示在程序運(yùn)行時發(fā)現(xiàn)的錯誤,通常是難以預(yù)防的。
- ?std::overflow_error??: 當(dāng)算術(shù)運(yùn)算超過表示范圍時拋出。
- ?std::underflow_error??: 當(dāng)算術(shù)運(yùn)算結(jié)果在正確的表示范圍內(nèi),但非正規(guī)化時拋出。
- ?std::range_error??: 當(dāng)計算的結(jié)果不在可表示的范圍內(nèi)時拋出。
- ?std::system_error??: 用于報告系統(tǒng)錯誤的異常。
-
std::bad_alloc??
當(dāng)動態(tài)內(nèi)存分配失敗時(如 new?? 表達(dá)式),std::bad_alloc?? 被拋出。
-
std::bad_cast???
使用動態(tài)轉(zhuǎn)換 (dynamic_cast??) 轉(zhuǎn)換到不兼容的類型時,拋出 std::bad_cast??。
-
std::bad_typeid???
當(dāng)使用類型信息功能(如 typeid?? 操作符)并且操作的對象是未定義類型時,拋出 std::bad_typeid?? 異常。
-
?std::bad_function_call???
當(dāng)調(diào)用一個空的 std::function?? 對象時,拋出 std::bad_function_call?? 異常。
-
#include <iostream>int main() {try{long long* p = new long long[0xFFFFFFF];}catch (const std::exception& e){std::cout << e.what() << std::endl;}return 0; }
自定異常
-
#include <iostream>class myException :public std::exception { public:myException(std::string message): m_Message(message){}virtual const char* what() const{return m_Message.c_str();}private:std::string m_Message; };int main() {try{myException obj("cc exception");throw obj;}catch (const std::exception& e){std::cout << e.what() << std::endl;}return 0; }