專家指出,長期作息不規律 + 用腦過度的危害很大,可能會誘發神經衰弱、失眠等疾病。我就是受害者之一,曾被失眠困擾了好幾年,不但入睡困難,還容易早醒。程序員要注意勞逸結合,多去健身房,多跑步,多打球,多陪女朋友旅游等,千萬不要熬夜,以為深夜寫代碼效率高,這樣會透支年輕的身體。程序的錯誤大致可以分為三種,分別是語法錯誤、邏輯錯誤和運行時錯誤:
#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;
}
運行結果: