簡單語句
(1)空語句
- 一種常見情況:當循環的全部工作在條件部分就可以完成時,會用到空語句
// 我們想要讀取輸入流的內容,直至遇到一個特定值,除此之外什麼事情都不做
while(cin>>s&&s!=sought)
;
不要漏寫分號,也不要在語句未結束時寫分號
(2)符合語句(塊)
塊不以分號作爲結束
語句作用域
- 在if、switch、while和for語句,在控制結構中聲明的變量,只有在相應語句的內部可見,語句結束,則變量也超出其作用範圍
條件語句
if語句
- if else語句的形式是
if(condition)
ststement
else
statement2
- 使用if else語句
const vector<string> scores={"F","D","C","B","A","A++"};
string lettergrade;
if (grade<60)
lettergrade=scores[0];
else
lettergrade=scores[(grade-50)/10];
- 嵌套if語句
// 加入的片段
if(grade % 10 > 7)
lettergrade += '+';
else if (grade % 10 < 3)
lettergrade += '-';
if(grade < 60)
lettergrade=scores[0];
else{
lettergrade=scores[(grade-50)/10];
if(grade != 100)
if(grade%10 > 7)
lettergrade +='+'';
else if(grade % 10<3)
lettergrade += '-'
}
- 懸垂else —— else 將會與最近的if匹配
switch語句
unsigned aCnt=0,eCnt=0,iCnt=0,oCnt=0,uCnt=0;
char ch;
while (cin>>ch){
switch(ch){
case 'a':
++aCnt;
break;
case 'e'
++eCnt;
break;
case 'i'
++iCnt;
break;
…
…
}
}
- case標籤必須是整型常量表達式
(2)有時,默認的switch行爲纔是程序真正需要的。每個case標籤只能對應一個值,但是有時候我們希望兩個或更多個值共享一組操作,因此故意省略掉break語句
unsigned vowelCnt=0;
switch (ch){
case 'a':
case 'e':
case 'i':
case 'o':
case 'u';
++vowelCnt;
break;
}
漏寫break容易引發缺陷
(3)default標籤
(4)switch內部變量的定義
- 一般將變量的定義在case中用塊包圍,以免造成不必要麻煩
迭代語句
while語句
定義在while條件部分或者while循環體內的變量每次迭代都經歷從創建到銷燬的過程
vector<int> v;
int i;
while (cin>>i)
v.push_back(i);
auto beg=v.begin();
while (beg != v.end() && *beg>=0)
++beg;
傳統for循環的執行流程
for(init-statemen;condition;expression)
statement
(1)傳統for循環的執行流程
(2)for語句頭中的多重定義
- init-statement可以定義多個對象,但是只能有一條聲明語句
// 記錄下v的大小,當達到原來的最後一個元素後結束循環
for(dealtype(v.size()) i=0,sz=v.size() ; i!=sz ; ++i)
v.push_back(v[i]);
(3)省略for語句頭的部分
- 其中一種,省略expression
vector<int> v;
for(int i ; cin>>i ; /*表達式爲空*/) //條件部分能夠改變i的值,無需表達式部分
v.push_back(i);
範圍for語句
- 形式如下
for(declaration : expression)
statement
- expression表示的必須是一個序列,比如用花括號括起來的初始值表、數組、vector、string等類型的對象,它們的共同特點是擁有能返回迭代器begin和end成員
- declaration定義一個變量,序列中每個元素都得能轉換成該變量的類型,確保相容的最好辦法是auto
vector<int> v={0,1,2,3,4,5,6,7,8,9};
for(auto &r : v)
r*+2;
do while語句
- 形式:
do
statement
while (condition);
- 小例子:不斷提醒用戶輸入一對數,然後求其和
string rsp;
do{
cout<<"please enter two values: "
int val1=0,val2=0;
cin>>val1>>val2;
cout<<"The sum of them is: "<<val1+val2<<"\n\n"
"More?Enter yes or no:";
cin>>rsp;
}while(!rsp.empty()&&rsp[0]!='n');
- 因爲do while想執行語句塊,後判斷條件,所以不允許在條件部分定義變量
跳轉語句
break語句
- break語句:終止離它最近的while、do while、for或switch語句,並從這些語句之後的第一條語句開始繼續執行
continue語句
- continue語句:終止最近的循環中的當前迭代並立即開始下一次迭代
string buf;
while(cin>>buf && !buf.empty())
if(buf[0] != '_')
continue; //接着讀取下一輸入
//程序處理到此處,即當前輸入是以下劃線開始的;接着處理buf……
}
goto語句
- goto語句:從goto語句無條件跳轉到同一函數內的另一條語句
不要在程序中使用goto語句,因爲它以理解和修改
goto label;
其中,label是用於標識一條語句的標示符,例如:“`end: return;“`
練習
do{
int sz=get_size();
}
while(sz<=0);
try語句塊和異常處理
- 異常處理機制 爲程序中異常檢測和異常處理這兩部分的協作提供支持,在C++中,異常處理包括:
- throws表達式
- 異常檢測部分使用throw表達式來表示它遇到了無法處理的問題
- try語句塊
- 異常處理部分使用try語句塊處理異常
- try語句塊以關鍵字try開始,並以一個或多個catch子句結
- try語句塊中代碼拋出的異常通常會被某一個catch字句處理
- 一套異常類
- 用於在throw表達式和相關的catch字句之間傳遞異常信息
- throws表達式
throw表達式
if(item1.isbn() != item2.isbn())
throw runtime_error("Data must refer to same ISBN");
// 程序執行到此,道標isbn號相同
cout<<item1+item2<<endl;
- 該異常是類型runtime_error的對象,其定義在stdexcept頭文件中
try語句塊
- 形式如下:
try{
program-statement
}catch(exception-declaration){
handler-statements
}catch(exception-declaration){
handler-statements
}//……
(1)編寫處理代碼
while(cin>>item1>>item2){
try{
//添加兩個Sales_item對象的代碼
//如果添加失敗,代碼拋出一個runtime_error異常
}catch(runtime_error err){
//提醒用戶兩個isbn必須一致
cout<<err.what()
<<"\n Try agin? Enter yes or no"<<endl;
char c;
cin>>c;
if(!cin || c=='n')
break; //跳出while循環
}
}
(2)函數在尋找處理代碼的過程中退出
- 在尋找處理代碼的過程與函數調用鏈剛好相反。當異常被拋出時,首先搜索拋出異常的函數。如果沒有招到匹配的catch子句,終止該函數,並在調用該函數的函數中繼續尋找。如果還是沒有找到匹配的catch子句,這個新的函數也被終止,繼續搜索調用它的函數。以此類推,沿着程序的執行路徑逐層回退,直到招到適當類型的catch子句爲止
- 如果最終還是沒有找到任何匹配的catch子句,程序將自動轉到名爲terminate的標準庫函數。該函數行爲與系統有關,一般都將導致程序非正常退出
標準異常
- exception頭文件定義了最常用的異常類exception。它只報告異常的發生,不提供任何額外的信息
- stdexcept頭文件定義了幾種常用的異常類
異常類 | 問題 |
---|---|
exception | 最常見的問題 |
runtime_erro | 只有在運行時才能檢測出的問題 |
range_error | 運行時錯誤:生成的結果超出了有意義的值域範圍 |
overflow_error | 運行時錯誤:計算上溢 |
underflow_error | 運行時錯誤:計算下溢 |
logic_error | 程序邏輯錯誤 |
domain_error | 邏輯錯誤:參數對應的結果值不存在 |
invalid_argument | 邏輯錯誤:無效參數 |
length_eroor | 邏輯錯誤:試圖創建一個超出該類型最大長度的對象 |
out_of_range | 邏輯錯誤:使用一個超出有效範圍的值 |
- new頭文件定義了bad_alloc異常類型
- type_info頭文件定義了bad_cast異常類型