專家指出,長期作息不規律 + 用腦過度的危害很大,可能會誘發神經衰弱、失眠等疾病。我就是受害者之一,曾被失眠困擾了好幾年,不但入睡困難,還容易早醒。程序員要注意勞逸結合,多去健身房,多跑步,多打球,多陪女朋友旅游等,千萬不要熬夜,以為深夜寫代碼效率高,這樣會透支年輕的身體。程序的錯誤大致可以分為三種,分別是語法錯誤、邏輯錯誤和運行時錯誤:
#include <iostream> #include <string> using namespace std; int main(){ string str = "http://c.biancheng.net"; char ch1 = str[100]; //下標越界,ch1為垃圾值 cout<<ch1<<endl; char ch2 = str.at(100); //下標越界,拋出異常 cout<<ch2<<endl; return 0; }運行代碼,在控制台輸出 ch1 的值後程序崩潰。下面我們來分析一下原因。
[ ]
不同,at() 會檢查下標是否越界,如果越界就拋出一個異常;而[ ]
不做檢查,不管下標是多少都會照常訪問。
所謂拋出異常,就是報告一個運行時錯誤,程序員可以根據錯誤信息來進一步處理。上面的代碼中,下標 100 顯然超出了字符串 str 的長度。由於第 6 行代碼不會檢查下標越界,雖然有邏輯錯誤,但是程序能夠正常運行。而第 8 行代碼則不同,at() 函數檢測到下標越界會拋出一個異常,這個異常可以由程序員處理,但是我們在代碼中並沒有處理,所以系統只能執行默認的操作,也即終止程序執行。
try{
// 可能拋出異常的語句
}catch(exceptionType variable){
// 處理異常的語句
}
try
和catch
都是 C++ 中的關鍵字,後跟語句塊,不能省略{ }
。try 中包含可能會拋出異常的語句,一旦有異常拋出就會被後面的 catch 捕獲。從 try 的意思可以看出,它只是“檢測”語句塊有沒有異常,如果沒有發生異常,它就“檢測”不到。catch 是“抓住”的意思,用來捕獲並處理 try 檢測到的異常;如果 try 語句塊沒有檢測到異常(沒有異常拋出),那麼就不會執行 catch 中的語句。exceptionType variable
指明了當前 catch 可以處理的異常類型,以及具體的出錯信息。我們稍後再對異常類型展開講解,當務之急是演示一下 try-catch 的用法,先讓讀者有一個整體上的認識。#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; }運行結果:
[ ]
不會檢查下標越界,不會拋出異常,所以即使有錯誤,try 也檢測不到。換句話說,發生異常時必須將異常明確地拋出,try 才能檢測到;如果不拋出來,即使有異常 try 也檢測不到。所謂拋出異常,就是明確地告訴程序發生了什麼錯誤。char ch1 = str[100000000];
,訪問第 100 個字符可能不會發生異常,但是訪問第 1 億個字符肯定會發生異常了,這個異常就是內存訪問錯誤。運行更改後的程序,會發現第 10 行代碼產生了異常,導致程序崩潰了,這說明 try-catch 並沒有捕獲到這個異常。拋出(Throw)--> 檢測(Try) --> 捕獲(Catch)
#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; }運行結果:
throw
關鍵字用來拋出一個異常,這個異常會被 try 檢測到,進而被 catch 捕獲。關於 throw 的用法,我們將在下節深入講解,這裡大家只需要知道,在 try 塊中直接拋出的異常會被 try 檢測到。#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; }運行結果:
#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; }運行結果: