[C]第二章--分支語句與迴圈語句(1)--知識解析
分支語句與迴圈語句
什麼是語句?
在C語言中,由一個分號;
隔開的一段程式碼就是語句,比如:
return 0;
/100 + 1 ;
/printf("a");
等都是語句.
分支語句
分支語句就是選擇結構
那if語句的語法結構是什麼樣的呢?以下列舉幾種經常使用的結構:
1
結構1
if(表示式)
語句;
結構2
if(表示式)
語句1;
else
語句2;
結構三
if(表示式1)
語句1;
else if(表示式2)
語句2;
else
語句3;
解釋一下:
如果表示式的結果為真,則語句1執行,否則表示式2執行.
在C語言中如何表示真假呢?
0 表示假
非0表示真
這與邏輯認知下的0為假,1為真有些差池,在C語言中非0即為真.
#include <stdio.h>
int main()[
if (表示式){
語句列表1;
}
else{
語句列表2;
}
return 0;
]
這裡是一個選擇語句的"坑".並不是跟在if之後的else之前的所有語句都會雨露均沾的執行到.
if/else預設只執行緊接著其的第一行程式碼,也就是說像這樣的語句列表並不會全部執行到.為了解決這個問題,我們引入程式碼塊的概念.
這裡的一對{ }
就是程式碼塊;
用大括號{ }
包裹的一系列語句的列表就是一個程式碼塊.
為了避免錯誤使用.建議讀者就將程式碼塊的使用加入平常選擇結構的使用.這樣習慣成自然,就完全不用糾結於到底有沒有執行這個語句列表了.這也有利於好的程式設計習慣的養成.
懸空else
一起來看下面這行程式碼:
#include <stdio.h>
int main(){
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("bingo\n");
else
printf("failed\n");
return 0;
}
這裡的else究竟和哪個if匹配的呢?
是不是很容易產生歧義?
這就是懸空else,難以直觀的看出來if…else…結構究竟是如何配對的問題,這在C語言的初學階段是很常見的.
- 解決方案:
1.適當的使用{ }
可以使程式碼的邏輯更加清晰,多用程式碼塊.
2.程式碼風格的統一很重要.
以下演示一下:
#include <stdio.h>
int main(){
int a = 0;
int b = 2;
if(a == 1){
if(b == 2)
printf("bingo\n");
}
else{
printf("failed\n");
}
return 0;
}
結論:
else總是與最近的if配對.
多分支
#include <stdio.h>
int main(){
int coding = 0;
printf("你會好好敲程式碼嗎?(選擇1或0)");
if(coding == 1) {
printf("堅持,你會有好成績");
}
else if(coding == 0){
printf("放棄回家睡大覺吧.");
}
else if(coding == -1){
printf("輸入錯誤啦");
}
return 0;
}
簡單的邏輯語句,就不多贅述了.
if書寫形式的對比
- 程式碼一:
if(condition)
return x;
return y;
- 程式碼二:
if(condition){
return x;
}
else{
return y;
}
- 程式碼三:
int num = 1;
if(num = 5){
printf("goal");
}
- 程式碼四:
int num = 1;
if(5 == num){
printf("goal");
}
比較上面4個程式碼,其實各有利弊.
- 程式碼一利用了
if
不加大括號只執行緊接的第一句語句,程式碼看起來很整潔,但是有些新手會混淆. - 程式碼二就比程式碼一直觀很多了,但是二者所陳述的內容都是一樣的,加上了不必要的大括號,在實際使用上就會顯得繁瑣很多.
- 程式碼三是一串和預期效果不太相同的程式碼,通過分析得知
num = 5
這個語句,按尋常邏輯應該是num == 5
的比較語句,而這裡因為少寫了一個等號=
,就使它變成了一個賦值語句,那麼這句語句再被if巢狀,他就成為了一定會判定成真的語句了.
所以一定要注意程式碼的嚴謹性. - 程式碼四中
5 == num
這樣書寫判斷語句雖然可以一定程度上提升程式碼安全性,因為編譯工具會自動檢查出程式碼缺陷並警告,但是這樣大大削減了程式碼的可讀性,這一句"有違常理"的語句,會使人很難讀懂其中的意思.
很不建議這麼書寫.
綜上所述:
程式碼一 和 程式碼三 的書寫方式建議使用
switch語句
switch語句與if語句不同的是:
switch用於多分支選擇,而if適合單分支(甚至"無分枝"的簡單判斷)
switch(整形表示式){
語句項;
}
而什麼是語句項?
是一些case語句.如下:
case 整型常量表達式:
語句;
在switch語句中,我們沒法直接實現分支
搭配break使用才能實現真正的分支.這也是其精髓之處.
比如:
#include <stdio.h>
int main(){
int day = 0;
switch(day){
case 1:
printf("Monday");
break;
case 2:
printf("Tuesday");
break;
case 3:
printf("Wednesday");
break;
case 4:
printf("Thursday");
break;
case 5:
printf("Friday");
break;
case 6:
printf("Saturday");
break;
default:
printf("Sunday");
break;
}
return 0;
}
default語句就是之前的case語句都為命中時執行的語句.
迴圈語句
1. while
我們已經掌握了if選擇語句,當條件滿足的情況下,if語句後的語句執行,否則不執行.但是這個語句只會執行一次.
但是我們發現生活中很多實際的例子是:同一件事情我們要完成很多次.
那我們怎麼做呢?
C語言中給我們引入了while語句,可以實現迴圈.
//while迴圈語法結構
while(表示式){
迴圈語句;
}
比如在螢幕上列印1-10的數字.
#include <stdio.h
int main(){
int i = 1;
while(i <= 10){
printf("%d ",i);
i++;
}
return 0;
}
break 語句
- break在迴圈中的作用:
其實在迴圈中只要遇到break,就停止後期所有的迴圈,直接跳出迴圈.
所以,while中的break是用於永久終止迴圈的.
continue 語句
- continue在迴圈中的作用:
本次continue後面的程式碼不會再執行,而是會直接跳轉到while語句的判斷部分,進行下一次迴圈的入口判斷.
所以,while中的continue是用於終止本次迴圈的
2. for
我們已經知道了while迴圈,但是為什麼還要一個for迴圈呢?
//for迴圈結構
for( 表示式1 ; 表示式2 ; 表示式3 )
迴圈語句;
- 表示式1為初始化部分,用於初始化迴圈變數的,在整個迴圈過程中只執行一次.
- 表示式2為條件判斷部分,用於判斷迴圈何時終止
- 表示式3為調整部分,用於更新迴圈變數.
[其實必要的情況下三個表示式都可省略]
用for迴圈在螢幕上列印1-10的數字
#include <stdio.h>
int main(){
int i = 0;
for(i = 1; i <= 10; i++){
printf("%d ",i);
}
return 0;
}
注:這裡int i
寫在for語句之前是C語言寫法
我們看到過很多次在for語言中的寫法for(int i = 0;xx;xx)
這樣是C++寫法
其實while中依然存在迴圈的三個必要條件,但是由於風格的問題使得三個部分偏離很遠,這樣查詢修改就不夠集中和方便,所以for迴圈更勝一籌.
for迴圈的使用頻率也最高.
一些建議:
- 不要在for迴圈體內修改迴圈變數,防止for迴圈失去控制
- 建議for語句的迴圈控制變數的取值採用"前開後閉區間"的寫法.[0 , 10)
3. do…while
//do...while語句格式
do
迴圈語句;
while(表示式);
特點: 迴圈至少執行一次,使用的場景很侷限.這裡就不過多講解了.
4. goto語句
goto本來不是為了迴圈而誕生的,但是與標籤配合標記跳轉可以實現迴圈,實踐中沒有goto語句也可以很容易的寫出程式碼,一般不會使用goto,除非一些"必要情況".
- 必要情況
->最常見的用法就是終止程式在某些深度巢狀的結構的處理過程,例如一次跳兩層或多層迴圈.
這樣的情況使用break是達不到目的的,它只能從最內層退出到上一層的迴圈.而goto就可以直接跳轉出去.
for(...){
for(...){
for(...){
if(disaster)
goto error;
}
}
}
error:
if(disaster)
//處理錯誤情況
goto這樣迴圈語句中的"旁門左道",還是建議大家儘量不要採納,