- 51單片機C語言開發教程
- 劉理云
- 4334字
- 2019-01-04 20:13:39
2.6 控制語句與程序設計
2.6.1 C語言語句概述
C語言的語句用來向計算機系統發出操作指令,一個語句經編譯后產生若干條機器指令。一個為實現特定目的的程序應當包含若干語句,C語句可以分為以下五類。
(1)控制語句
控制語句完成一定的控制功能,C語言有9種控制語句,它們是:
(2)函數調用語句
在C語言中,若函數僅進行某些操作而不返回函數值,這時函數的調用可作為一條獨立的語句,稱為函數調用語句。其一般形式為
函數名(實際參數表);
例如:DelayTime(1000);
Printf(“hello!\n);
(3)表達式語句
由一個表達式構成一個語句。最典型的是,由賦值表達式構成一個賦值語句。
a=3
是一個賦值表達式,而
a=3;
是一個賦值語句。可以看到一個表達式的最后加一個分號就成了一個語句。一個語句必須在最后出現分號,分號是語句中不可缺少的一部分。例如:
任何表達式都可以加上分號而成為語句,例如
是一語句,作用是使i值加1。又如
也是一個語句,作用是完成x+y的操作,它是合法的,但是并不把x+y的和賦給另一變量,所以它并無實際意義。
(4)空語句
如果一條語句只有語句結束符號“;”則稱為空語句。例如
;
空語句在執行時不產生任何動作,但仍有一定的作用。
(5)復合語句
在C語言中,把多條語句用一對大括號括起來組成的語句稱為復合語句。其一般格式為
例如:
注意:大括號之后不再加分號。
復合語句雖然可有多條語句組,但它是一個整體,相當于一條語句,凡可以使用單一語句的位置都可以使用復合語句。
2.6.2 賦值語句
在任何合法的賦值表達式的尾部加上一個分號就構成了賦值語句。賦值語句的一般形式為
例如:“a=b+c”是賦值表達式,而“a=b+c;”則是賦值語句。
賦值語句的作用是先計算賦值號右邊表達式的值,然后將該值賦給賦值號左邊的變量。例如:
賦值語句不可被包括在其他表達式之中,例如
在if語句中的“a=b”不是賦值語句而是賦值表達式,這樣寫是合法的。如果寫成
就錯了。
2.6.3 if語句
if語句用來判定所給定的條件是否滿足,根據判定的結果(真或假)決定執行給出的兩種操作之一。
2.6.3.1 if語句的三種形式
(1)if語句形式一
if(表達式)語句;
其中,if是C語言的關鍵字;表達式兩側的小括號不可少,表達式的類型任意,如果表達式的值為非零,按真處理,如果表達式的值為零,按假處理;最后的語句可以是C語言任意合法的語句。
這種if語句的執行過程如圖2-4所示。先計算表達式,如果表達式的值為真(非零),則執行其后的語句;否則,順序執行if語句后的下一條語句。

圖2-4 形式一if語句執行過程
(2)if語句形式二
if(表達式)語句1;
表達式類型任意,語句1和語句2可以是任意合法的語句。
這種if語句的執行過程如圖2-5所示。先計算表達式,如果表達式的值為真(非零),則執行語句1;否則,執行語句2。

圖2-5 形式二if語句執行過程
注意:①在else前面有一分號,這是由于分號是C語句中不可缺少的部分,這個分號是if語句中的內嵌語句所要求的,如果無此分號,則出現語法錯誤。但應注意,不要誤認為上面是兩個語句,它們都屬于同一if語句。else子句不能作為語句單獨使用,它必須是if語句的一部分,與if配對使用。
②在if和else后面可以只含一個內嵌的操作語句(如上例),也可以有多個操作語句,此時用大括號“{}”將幾個語句括起來成為一個復合語句。如考慮下面程序的輸出結果:
注意在“{}”外面不需要再加分號,因為“{}”內是一個完整的復合語句,不需另附加分號。
(3)if語句形式三
這種if語句的執行過程如圖2-6所示。

圖2-6 形式三if語句執行過程
2.6.3.2 if語句的嵌套
在if語句中又包含一個或多個if語句稱為if語句的嵌套,它有如下四種形式:
形式1:
形式2:
形式3:
形式4:
應當注意if與else的配對關系。從最內層開始,else總是與它上面最近的且未曾配對的if配對。假如寫成:
編程者把else寫在與第一個if(外層if)同一列上,希望else與第一個if對應,但實際上else是與第二個if配對,因為它們相距最近。因此最好使內嵌if語句也包含else部分,如內嵌形式4,這樣if的數目和else的數目相同,從內層到外層一一對應,不致出錯。如果if與else的數目不一樣,為實現程序設計者的企圖,可以加大括號來確定配對關系。如內嵌形式2。這時“{}”限定了內嵌if語句的范圍,因此else與第一個if配對。
2.6.4 switch語句
switch語句的一般形式如下:
例如:
說明:
①switch是關鍵字,其后面大括號里括起來的部分稱為switch語句體。要特別注意必須寫這一對大括號。
②switch后(表達式)的運算結果可以是整型、字符型或枚舉型表達式等,(表達式)兩邊的括號不能省略。
③case也是關鍵字,與其后面<常量表達式>合稱為case語句標號。<常量表達式>的值在運行前必須是確定的,不能改變,因此不能是包含變量的表達式,而且數據類型必須與switch后面<表達式>的類型一致。如:
④case和常量之間要有空格,case后面的常量之后有“:”。每一個case的常量表達式的值必須互不相同,否則就會出現相互矛盾的現象(對表達式的同一個值,有兩種或多種執行方案)。
⑤default也是關鍵字,起標號的作用。代表所有case標號之外的那些標號。default可以出現在語句體中任何標號位置上。在switch語句體中也可以無default標號。
⑥<語句序列1>、<語句序列2>等,可以是一條語句,也可以是若干語句。如果在case后面包含若干執行語句,可以不必用大括號括起來,會自動順序執行本case后面所有的執行語句,當然加上大括號也可以。
⑦各個case的出現次序不影響執行結果,例如,可以先出現“case‘D’:…”,然后是“case‘A’:…”。必要時,case語句標號后的語句可以不寫。
⑧switch語句的執行過程:switch語句的執行過程如圖2-7所示。首先計算switch后面表達式的值,當表達式的值與某一個case后面的常量表達式的值相等時,就執行此case后面的語句,若所有的case中的常量表達式的值都沒有與表達式的值匹配的,就執行default后面的語句。執行完一個case后面的語句后,流程控制轉移到下一個case繼續執行。“case常量表達式”只是起語句標號作用,并不是在該處進行條件判斷。在執行switch語句時,根據switch后面表達式的值找到匹配的入口標號,就從此標號開始執行下去,不再進行判斷。例如上面的例子中,若grade的值等于‘A',則將連續輸出:

圖2-7 switch語句的執行過程
因此,應該在執行一個case分支后,使流程跳出switch結構,即終止switch語句的執行,可以用一個break語句來達到此目的,如圖2-8所示。將上面的switch結構改寫成如下:

圖2-8 使用break語句后switch語句的執行過程
最后一個分支(default)可以不加break語句。如果grade的值為‘B',則只輸出“74~84”。
⑨多個case可以共用一組執行語句,如:
grade的值為‘A'、‘B'、‘C’時都執行同一組語句。
2.6.5 goto語句以及用goto語句構成循環
下面首先來介紹goto語句以及用goto語句構成循環。goto語句為無條件轉向語句,它的一般形式為:
說明:
①語句標號用標識符表示,它的命名規則與變量名相同,即由字母、數字和下畫線組成,其第一個字符必須為字母或下畫線。不能用整數來作標號。
②標號只能出現在goto所在函數內,且唯一。
③標號只能加在可執行語句前面。
④結構化程序設計方法主張限制使用goto語句,因為goto語句用多了將使程序流程無規律、可讀性差。
【例2-15】用if和goto語句構成循環,求1~100的和。
2.6.6 while語句與do-while語句
2.6.6.1 while語句
while語句用來實現“當型”循環結構。其一般形式如下:
其中“表達式”可以是C語言中任意合法的表達式,其作用是控制循環體是否執行;“循環體”是循環語句中需要重復執行的部分,可以是一條簡單的可執行語句,也可以是用大括號括起來的復合語句。
while語句的執行過程如圖2-9所示。①先計算表達式的值;②若表達式的值為非0,則執行循環體至步驟①;若表達式的值為0,則退出while循環。

圖2-9 while語句的執行過程
說明:
①循環體如果含有一個以上的語句,應該用大括號括起來,以復合語句形式出現。如果不加大括號,則while語句的范圍只到while后面第一個分號處。
②要定義循環控制變量。要確定循環變量的初值、終值、增量(步長)、循環結束條件。
③要保證每執行一次循環體,循環控制變量的值按增量向終值靠近一些,即避免死循環。
【例2-16】用while循環求1~100的和。
2.6.6.2 do-while語句
do-while語句用來實現“直到型”循環結構。其一般形式為:
其中,“表達式”可以是C語言中任意合法的表達式,其作用是控制循環體是否執行;“循環體”可以是C語言中任意合法的可執行語句;最后的“;”不可丟,表示do-while語句結束。
do-while語句的執行過程如圖2-10所示。

圖2-10 do-while語句的執行過程
①先執行循環體中的語句。
②計算表達式的值,若表達式的值為真(非0),則轉步驟①;若表達式的值為假(0),則退出while循環。
【例2-17】用do-while語句構成循環求1~100的和。
2.6.7 for語句
for語句的一般形式如下:
for(表達式1;表達式2;表達式3)循環體
for是關鍵詞,后面的小括號不能省,其中,“表達式1”“表達式2”“表達式3”可以是C51語言中任意合法的表達式,3個表達式之間用“;”隔開,其作用是控制循環體是否執行;循環體可以是C語言中任意合法的可執行語句。
for語句的執行過程如圖2-11所示,具體步驟如下:

圖2-11 for語句執行過程
①先求解表達式1。
②求解表達式2,若其值為真(非0),則執行循環體,循環體執行完后,再執行下面第③步。若表達式2的值為假,則結束循環,轉到第⑤步。
③若表達式2的值為真,執行完循環體后,求解表達式3。
④轉回一面第②步驟繼續執行。
⑤執行for語句下面的語句。
for語句的典型應用形式:
說明:
①for語句一般形式中的“表達式1”可以省略,此時應在for語句之前給循環變量賦初值。注意省略表達式1時,其后的分號不能省略。如:
執行時,跳過“求解表達式1”這一步,其他不變。
②如果表達式2省略,但其后面的分號不能省,即不判斷循環條件,循環無終止地進行下去。也就是認為表達式2始終為真。如:
③表達式3也可以省略,但此時程序設計者應另外設法保證循環能正常結束。例如:
本例把i++的操作不放在for語句的表達式3的位置處,而作為循環體的一部分,效果是一樣的,都能使循環正常結束。循環體如果不止一個語句,則循環體語句要用大括號括起來,構成復合語句,如上例,如果不用大括號括起來,則循環體只到“sum=sum+i;”。
④可以省略表達式1和表達式3,只有表達式2,即只給循環條件。如:
⑤三個表達式都可省略,如
即不設初值,不判斷條件(認為表達式2為真),循環變量不增值,無終止地執行循環體。相當于“while(1)語句”。
⑥表達式1可以是設置循環變量初值的賦值表達式,也可以是與循環變量無關的其他表達式。如
表達式3也類似。
表達式1和表達式3可以是一個簡單的表達式,也可以是逗號表達式,即包含一個以上的簡單表達式,中間用逗號間隔。如:
表達式1和表達式3都是逗號表達式,各包含兩個賦值表達式,即同時設兩個初值,使兩個變量增值。
2.6.8 break語句和continue語句
(1)break語句
break語句的一般形式:
break語句的功能是:①終止所在的switch語句;②跳出本層循環體,從而提前結束本層循環。
說明:
①break只能終止并跳出最近一層的結構;
②break不能用于循環語句和switch語句之外的任何其他語句之中。
(2)continue語句
continue語句的一般形式:
continue語句的功能是:用于循環體內結束本次循環,接著進行下一次循環的判定。