C語言程序設(shè)計(jì)新視角-程序語句_第1頁
C語言程序設(shè)計(jì)新視角-程序語句_第2頁
C語言程序設(shè)計(jì)新視角-程序語句_第3頁
C語言程序設(shè)計(jì)新視角-程序語句_第4頁
C語言程序設(shè)計(jì)新視角-程序語句_第5頁
已閱讀5頁,還剩120頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

程序語句NewPerspectiveforCProgranmming【主要內(nèi)容】基本程序語句;同類程序語句的特點(diǎn)、相互間的聯(lián)系、選用條件等;流程圖分析程序的效率訓(xùn)練;自頂向下算法設(shè)計(jì)的訓(xùn)練;讀程序的訓(xùn)練;語句調(diào)試要點(diǎn)的介紹?!緦W(xué)習(xí)目標(biāo)】掌握用基本語句進(jìn)行順序、選擇和循環(huán)結(jié)構(gòu)程序設(shè)計(jì)的方法;掌握表達(dá)式語句的格式,理解表達(dá)式與表達(dá)式語句的區(qū)別;掌握C語言的基本控制結(jié)構(gòu)和基本控制語句的使用方法掌握簡(jiǎn)單的程序調(diào)試方法;了解測(cè)試用例選取方法。13.1程序的語句與結(jié)構(gòu)23.2順序結(jié)構(gòu)33.3選擇結(jié)構(gòu)43.4循環(huán)結(jié)構(gòu)53.5本章小結(jié)目錄CONTENTS13.1程序的語句與結(jié)構(gòu)23.2順序結(jié)構(gòu)33.3選擇結(jié)構(gòu)43.4循環(huán)結(jié)構(gòu)53.5本章小結(jié)目錄CONTENTS3.1程序的語句與結(jié)構(gòu)

從程序流程的角度來看,程序可以分為三種基本結(jié)構(gòu),即順序結(jié)構(gòu)、分支(選擇)結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。這三種基本結(jié)構(gòu)可以組成所有的復(fù)雜程序。C程序語句類型C程序的結(jié)構(gòu)

在實(shí)際編程過程中常將這三種結(jié)構(gòu)相互結(jié)合以實(shí)現(xiàn)各種算法,設(shè)計(jì)出相應(yīng)程序。順序結(jié)構(gòu)分支結(jié)構(gòu)循環(huán)結(jié)構(gòu)C程序的組成從程序的模塊化結(jié)構(gòu)來看,C程序由函數(shù)組成,必須有一個(gè)主函數(shù),可以有0個(gè)到多個(gè)子函數(shù),C程序=主函數(shù)+子函數(shù)13.1程序的語句與結(jié)構(gòu)23.2順序結(jié)構(gòu)33.3選擇結(jié)構(gòu)43.4循環(huán)結(jié)構(gòu)53.5本章小結(jié)目錄CONTENTS3.2順序結(jié)構(gòu)語句按照書寫的順序由上至下逐條執(zhí)行

順序結(jié)構(gòu)的流程【例3-1】順序結(jié)構(gòu)程序的例子從鍵盤輸入4位學(xué)生的學(xué)號(hào)和英語考試成績(jī),打印這4人的學(xué)號(hào)和成績(jī),最后輸出4人的英語平均成績(jī)。

1 /*順序結(jié)構(gòu)程序的例子*/

2 #include<stdio.h>

3 intmain()

4 {

5 intnumber1,number2,number3,number4;/*設(shè)4個(gè)學(xué)號(hào)*/

6 floatgrade1,grade2,grade3,grade4;/*設(shè)4個(gè)成績(jī)*/

7 floatave;/*平均成績(jī)*/

8

9 printf("inputnumber:\n");/*提示*/

10 /*輸入4個(gè)學(xué)號(hào)*/

11 scanf("%d%d%d%d",&number1,&number2,&number3,&number4);

12 printf("inputgrader:\n");/*提示*/

13 /*輸入4個(gè)成績(jī)*/

14 scanf("%f%f%f%f",&grade1,&grade2,&grade3,&grade4);

15

16 ave=(grade1+grade1+grade1+grade1)/4;/*計(jì)算平均分*/

17 printf("%d:%f\n",number1,grade1);

18 printf("%d:%f\n",number2,grade2);

19 printf("%d:%f\n",number3,grade3);

20 printf("%d:%f\n",number4,grade4);

21 printf("average=%f\n",ave);

22 return0;

23 }程序結(jié)果:

inputnumber:

1234

inputgrader:

86927564

1:86.000000

2:92.000000

3:75.000000

4:64.000000

average=86.000000這個(gè)程序中,重復(fù)的類似變量和語句比較多,在后續(xù)的章節(jié)中可以看到改進(jìn)的處理方法。13.1程序的語句與結(jié)構(gòu)23.2順序結(jié)構(gòu)33.3選擇結(jié)構(gòu)43.4循環(huán)結(jié)構(gòu)53.5本章小結(jié)目錄CONTENTS3.3選擇結(jié)構(gòu)選擇程序結(jié)構(gòu)——先判斷給定的條件,再根據(jù)判斷的結(jié)果來控制程序的流程C條件語句3.3.1二選一結(jié)構(gòu)——if語句

if語句有單路選擇和雙路選擇兩種基本形式說明:

(1)圖3.2中的語句A、B既可以是一條語句,也可以是復(fù)合語句。以后各種C語句的語法中凡出現(xiàn)“語句”的地方,其含義都相同。

(2)圖3.2中的表達(dá)式,理論上是條件或邏輯表達(dá)式,其結(jié)果為“真”或“假”。1.單路選擇的if語句

if(表達(dá)式)語句A;執(zhí)行過程:執(zhí)行if語句時(shí),首先計(jì)算緊跟在if后面一對(duì)圓括號(hào)中的表達(dá)式的值。如果表達(dá)式的值為非零(“真”),則執(zhí)行其后的if子句,然后執(zhí)行if語句后面的下一條語句;如果表達(dá)式的值為零(“假”),則跳過if子句,直接執(zhí)行if語句后面的下一條語句。2.雙路選擇的if語句

if(表達(dá)式)語句A;

else語句B;執(zhí)行過程:執(zhí)行if-else語句時(shí),首先計(jì)算緊跟在if后面一對(duì)圓括號(hào)內(nèi)表達(dá)式的值。如果表達(dá)式的值為非零(“真”),則執(zhí)行if子句,然后跳過else子句,去執(zhí)行if-else語句之后的下一條;如果表達(dá)式的值為零(“假”),則跳過if子句,會(huì)執(zhí)行else子句,執(zhí)行完之后接著執(zhí)行if-else語句之后的下一條語句?!纠?-2】if語句的例子1

用if語句實(shí)現(xiàn)表3.4的功能。y與x的關(guān)系式1

【解】

if(x>2)y=1;

elsey=2;【例3-3】if語句的例子2

用if語句實(shí)現(xiàn)表3.5的功能?!窘夥ㄒ弧?/p>

if(x>=0&&x<=2)y=0;

if(x>2)y=1;

if(x<0)y=2;

程序的執(zhí)行過程是怎樣的呢?直接讀程序是不大容易看得清楚的,畫出流程圖就一目了然了【例3-3】if語句的例子2圖3.3例3-3方法1從流程圖3.3中,我們可以發(fā)現(xiàn)什么問題呢?

(1)若x滿足0≤x≤2,則在第一次遇到的條件判斷中為真,得到結(jié)果y=0,后面再判斷x>2和判斷x<0就是多余做的工作了。

(2)若x滿足x<2,則判斷x<0就是多余做的工作了。

由此,我們可以對(duì)此程序得出評(píng)價(jià)——可讀性好,效率不高?!纠?-3】if語句的例子2改進(jìn)后的程序同方法一相比,能看出x和y的關(guān)系嗎?

答:是不太容易看清楚,也就是說,此程序的可讀性不好。那是不是有程序又清晰,執(zhí)行效率又高的方法呢?我們看一下解法三。【解法二】

if(x>=0)&&(x<=2)y=0;

else{if(x>2)y=1;

elsey=2;

}【例3-3】if語句的例子2

【解法三】由方法2改進(jìn)后的流程

y=0;

if(x>2)y=1;

elseif(x<0)y=2;

改進(jìn)后的效果依然是從流程圖3.5看起來比較直觀,到此,程序可讀性好、執(zhí)行效率高的目標(biāo)就達(dá)到了。

相對(duì)于程序語句,流程圖可以幫助我們更直觀清晰地觀察程序的執(zhí)行狀況。

嵌套if-else語句規(guī)則實(shí)例1:

if()

if()語句1;

else語句2;

實(shí)例2:

if()

{

if()語句1;

}

else語句2;

兩個(gè)嵌套的條件語句if-else實(shí)例中,else和哪個(gè)if配對(duì),都有兩種可能性。為了避免二義性,C語言中有相應(yīng)的規(guī)則。注:復(fù)合語句是用{}括起來的一組語句。

if語句的嵌套結(jié)構(gòu)中,else總是與最近的if匹配的。

【例3-4】if語句的例子3求a、b、c三個(gè)整數(shù)中最大者(a、b、c的值通過鍵盤輸入)。數(shù)據(jù)分析按照設(shè)計(jì)算法的第一個(gè)步驟,應(yīng)該選擇上述第一種情形來設(shè)計(jì)處理的流程,待算法設(shè)計(jì)完畢,再去測(cè)試數(shù)據(jù)的特殊情形和臨界狀態(tài),如果有問題,再進(jìn)行修改?!纠?-4】if語句的例子3【解法一】根據(jù)題目的要求,可以給出相應(yīng)的頂部偽代碼以及細(xì)化的偽代碼【例3-4】if語句的例子3【例3-4】if語句的例子3例3-4特例情形測(cè)試用例【例3-4】if語句的例子3

1 /*求出整數(shù)a、b、c三者中大者,放入max*/

2 #include<stdio.h>

3 intmain()

4 {

5 inta,b,c,max;

6

7 scanf("%d,%d,%d",&a,&b,&c);/*通過鍵盤輸入a、b、c*/

8 if(a>b)

9 {

10 if(a>c)

11 {

12 max=a;

13 }

14 else

15 {

16 max=c;/*max取a、c中的大者*/

17 }

18 }

19 else

20 {

21 if(b>c)

22 {【例3-4】if語句的例子3

23 max=b;

24 }

25 else

26 {

27 max=c;/*max取b、c中的大者*/

28 }

29 }

30 printf("max=%d",max);/*輸出結(jié)果*/

31 return0;

32 }成對(duì)括號(hào),成對(duì)輸入?!纠?-4】if語句的例子3

【解法二】方法一中,既然max記錄最大值,則可以在a與b的比較時(shí)就使用它,【例3-4】if語句的例子3實(shí)現(xiàn)情形二:

if(max>c)max=max;

elsemax=c;

printf(…);

其中的max=max語句實(shí)屬多余。實(shí)現(xiàn)情形一:

if(max>c)printf(…);

else{max=c;printf(…);}這種情形只有一個(gè)輸出與流程不完全對(duì)應(yīng)。

對(duì)應(yīng)條件max>c的二選一語句,寫的時(shí)候會(huì)有如下問題?!纠?-4】if語句的例子3

怎么讓程序與流程圖完全對(duì)應(yīng)起來呢?實(shí)現(xiàn)情形三:把流程中的max<c條件改成max>c。

if(max<c)max=c;printf(…)【例3-4】if語句的例子3

【解法三】用條件表達(dá)式:

max=(a>b)?a:b;

max=(max>c)?max:c;

評(píng)價(jià):此法簡(jiǎn)潔而清晰。3.3.2多選一結(jié)構(gòu)——swich語句

在實(shí)際應(yīng)用中,要在多種情況中選擇一種情況,執(zhí)行某一部分語句,當(dāng)然可以使用嵌套的if或ifelseif語句來處理,但其分支過多,程序冗長(zhǎng)、難讀且不夠靈巧。

【例3-5】多選一的例子輸入百分制成績(jī)score,轉(zhuǎn)換成相應(yīng)的五分制成績(jī)grade并輸出。分?jǐn)?shù)和等級(jí)的對(duì)應(yīng)關(guān)系見表3.12?!纠?-5】多選一的例子用if語句實(shí)現(xiàn)的方法如下:

1 #include<stdio.h>

2 intmain()

3 {

4intscore;

5 printf("Pleaseinputscore:");

6 scanf("%d",&score);/*輸入成績(jī)*/

7 if(score>100||score<0)

8 printf("inputerror!");/*異常處理*/

9 elseif(score>=90)printf("%d--A\n",score);

10 elseif(score>=80)printf("%d--B\n",score);

11 elseif(score>=70)printf("%d--C\n",score);

12 elseif(score>=60)printf("%d--D\n",score);

13 elseif(score>=0)printf("%d--E\n",score);

14 elseprintf("Inputerror\n");

15 return0;

16 }評(píng)價(jià):程序的分支太多,可讀性差。多分支選擇的switch語句多分支選擇的switch語句

多選一結(jié)構(gòu)中的“表達(dá)式”與if語句中的“表達(dá)式”有區(qū)別嗎?

答:從原則上說,if語句中的“表達(dá)式”應(yīng)該是關(guān)系或邏輯表達(dá)式,結(jié)果是邏輯值;

switch語句中的“表達(dá)式”應(yīng)該是運(yùn)算表達(dá)式,結(jié)果是數(shù)值。

多分支選擇的switch語句switch(表達(dá)式){case常量1:語句系列A;[break;]

case常量2:語句系列B;[break;]

case常量n:語句系列N;[break;]

default:語句系列N+1;

}

注:[]內(nèi)的內(nèi)容為可選項(xiàng)。

switch語句執(zhí)行過程如下:

(1)當(dāng)執(zhí)行switch語句時(shí),首先計(jì)算緊跟其后的一對(duì)括號(hào)中的表達(dá)式的值,然后在switch語句體內(nèi)尋找與該值吻合的case標(biāo)號(hào)(常量1~常量n)。

(2)如果有與該值相等的標(biāo)號(hào),則執(zhí)行該標(biāo)號(hào)后開始的各語句,包括在其后的所有case和default中的語句,直到switch語句結(jié)束。

(3)如果沒有與該值相等的標(biāo)號(hào),并且存在default標(biāo)號(hào),則從default標(biāo)號(hào)后的語句開始執(zhí)行,直到switch語句體結(jié)束。

(4)如果沒有與該值相等的標(biāo)號(hào),同時(shí)又沒有default標(biāo)號(hào),則跳出switch語句體,去執(zhí)行switch語句之后的語句。多分支選擇的switch語句說明:

(1)break語句的作用:跳出switch語句體。

(2)常量1~常量n可以是數(shù)值常量、符號(hào)常量,它們互不相等。

(3)每個(gè)case分支可有多條語句,可不用{}括起來。

(4)不要忽略default處理,在有異常情形時(shí),即表達(dá)式的值沒有在所列出的所有case中時(shí),有可能會(huì)造成程序運(yùn)行崩潰。(5)switch后表達(dá)式的值可為任何類型的數(shù)據(jù),但最好不要是實(shí)數(shù),原因是什么呢?我們?cè)诮榻B數(shù)據(jù)類型時(shí),關(guān)于實(shí)數(shù),有一條規(guī)則是“實(shí)數(shù)避免比相等”,因?yàn)閷?shí)數(shù)比相等有可能會(huì)得出錯(cuò)誤的結(jié)果。

不要忽略了default情形的處理。【例3-6】開關(guān)語句的例子1用switch語句實(shí)現(xiàn)百分制成績(jī)轉(zhuǎn)換成相應(yīng)的五分制的功能。語句框架

switch(表達(dá)式)

{

case常量1:printf("%d-----A\n",score);break

case常量2:printf("%d-----B\n",score);break;

case常量3:printf("%d-----C\n",score);break;

case常量4:printf("%d-----D\n",score);break;

case常量5:printf("%d-----E\n",score);break;

default:printf("Inputerror\n");

}現(xiàn)在的關(guān)鍵問題是要確定switch(表達(dá)式)中表達(dá)式的形式是什么。score的正常取值范圍是0~100,要找到一個(gè)公式,把它們分成5個(gè)非均勻的級(jí)別,這可能有些困難。我們可以考慮將score縮小10倍,分成10級(jí)【例3-6】開關(guān)語句的例子1switch(score/10){

case10:

case9:printf("%d-----A\n",score);breakcase8:printf("%d-----B\n",score);break;

case7:printf("%d-----C\n",score);break;

case6:printf("%d-----D\n",score);break;

case5:

case4:

case3:

case2:

case1:

case0:printf("%d-----E\n",score);break;

default:printf("Inputerror\n");

}(2)score=100時(shí),此分支無語句,語法規(guī)定:可以再找下面的語句printf(“%d-----A\n”,score)執(zhí)行,直到遇到break語句,才跳出switch。

(3)對(duì)于score<60時(shí)的情形,其執(zhí)行狀況與score=100時(shí)是類似的。score/10的結(jié)果為整型值【例3-6】開關(guān)語句的例子1用樣例數(shù)據(jù)測(cè)試結(jié)果,當(dāng)100<score<110時(shí),score/10=10,程序結(jié)果顯示成績(jī)是“A”,這顯然是錯(cuò)誤的。測(cè)試用例【例3-6】開關(guān)語句的例子1

scanf("%d",&score);

if(score>100&&score<110)score=110;

switch(score/10)

{

case10:

case9:printf("%d-----A\n",score);break;

case8:printf("%d-----B\n",score);break;

case7:printf("%d-----C\n",score);break;

case6:printf("%d-----D\n",score);break;

case5:

case4:

case3:

case2:case1:

case0:printf("%d-----E\n",score);break;

default:printf("Inputerror\n");

}改進(jìn)后的程序【例3-7】開關(guān)語句的例子2將下列語句改寫為switch語句(a為整數(shù)):

if(a<5)&&(a>=0)

{if(a>2)

{if(a<4)x=1;

elsex=2;

}

elsex=3;

}【例3-7】開關(guān)語句的例子2程序?qū)崿F(xiàn):

switch(a)

{case0:

case1:

case2:x=3;break;

case3:x=1;break;

case4:x=2;break;

default:printf("aiserror\n");

}若a為實(shí)數(shù),switch語句又該如何寫?【例3-7】開關(guān)語句的例子2當(dāng)a=2時(shí),x=3;當(dāng)2<a<3時(shí),x=1。只要在程序中分清這兩種情況即可。switch((int)a)

{case0:

case1:

case2:if(a>2)x=1;

elsex=3;break;

case3:x=1;break;

case4:x=2;break;

default:printf("aiserror\n");

}【例3-7】開關(guān)語句的例子2

問題2:程序測(cè)試時(shí)方便嗎?

答:測(cè)一個(gè)數(shù)就得重新運(yùn)行一次程序,很不方便。理想的測(cè)試運(yùn)行,應(yīng)該是把所有數(shù)據(jù)都測(cè)試完,程序再退出。我們?cè)趯W(xué)習(xí)了循環(huán)語句后,就可以達(dá)到這個(gè)目的了。

問題1:這個(gè)程序至少應(yīng)該測(cè)試哪些點(diǎn)?

答:測(cè)試原則我們已經(jīng)知道了,要測(cè)試正常的值、邊界值、特殊值和異常情形,測(cè)試數(shù)據(jù)可以有表3.17里的這些?!纠?-8】開關(guān)語句的例子3

設(shè)計(jì)程序,完成用戶可以通過鍵盤輸入數(shù)值,進(jìn)行加、減、乘、除的運(yùn)算。

【解】先對(duì)數(shù)據(jù)的輸入、輸出做一個(gè)分析,具體見表3.18?!纠?-8】開關(guān)語句的例子3根據(jù)輸入數(shù)據(jù)的特點(diǎn),可以用運(yùn)算符做case值,用switch語句實(shí)現(xiàn)如下:

1 #include<stdio.h>

2 intmain()

3 {

4 floata,b;/*定義兩個(gè)要運(yùn)算的數(shù)*/

5 charc;/*運(yùn)算符*/

6

7 printf("inputexpression:a+(-,*,/)b\n");/*提示輸入*/

8 scanf("%f%c%f",&a,&c,&b);/*按序輸入計(jì)算式*/

9 switch(c)/*對(duì)運(yùn)算符分情形處理*/

10 {

11 case'+':

12 printf("%f\n",a+b);

13 break;

14 case'-':【例3-8】開關(guān)語句的例子3

15 printf("%f\n",a-b);

16 break;

17 case'*':

18 printf("%f\n",a*b);

19 break;

20 case'/':

21 printf("%f\n",a/b);

22 break;

23 default:

24 printf("inputerror\n");

25 }

26 return0;

27 }

if語句和switch語句中的表達(dá)式含義一樣嗎?

答:if語句中的表達(dá)式是條件/邏輯表達(dá)式,其結(jié)果為真或假;switch語句中的表達(dá)式是算術(shù)表達(dá)式,其結(jié)果為數(shù)值。13.1程序的語句與結(jié)構(gòu)23.2順序結(jié)構(gòu)33.3選擇結(jié)構(gòu)43.4循環(huán)結(jié)構(gòu)53.5本章小結(jié)目錄CONTENTS3.4循環(huán)結(jié)構(gòu)在不少實(shí)際問題中有許多具有規(guī)律性的重復(fù)操作,往往用順序結(jié)構(gòu)的程序?qū)崿F(xiàn)方法顯得繁瑣,甚至是幾乎是不可忍受的。循環(huán)引例

從鍵盤輸入4位學(xué)生的學(xué)號(hào)和英語考試成績(jī),輸出4人的英語平均成績(jī)。

用循環(huán)的方法實(shí)現(xiàn)

循環(huán)結(jié)構(gòu)是程序設(shè)計(jì)語言中最重要的控制結(jié)構(gòu),把需要反復(fù)多次執(zhí)行的任務(wù)設(shè)計(jì)成循環(huán)結(jié)構(gòu),不僅可以減少源程序重復(fù)書寫的工作量,簡(jiǎn)化程序設(shè)計(jì)過程,還可以減少源程序占用的內(nèi)存空間,這是程序設(shè)計(jì)中最能發(fā)揮計(jì)算機(jī)特長(zhǎng)的程序結(jié)構(gòu)。C語言中的四種循環(huán)四種循環(huán)可以用來處理同一問題,一般情況下它們可以互相替換,goto循環(huán)while循環(huán)do-while循環(huán)for循環(huán)循環(huán)三要素循環(huán)體:一組被重復(fù)執(zhí)行的語句稱之為循環(huán)體。

循環(huán)是由循環(huán)體及循環(huán)三要素兩大部分組成的,在把握住了循環(huán)問題的三要素后,各種循環(huán)形式的轉(zhuǎn)換就是很容易的事情了。

常用的三種循環(huán)結(jié)構(gòu)while、do-While和for中,有三個(gè)要素是相同的(1)循環(huán)初始條件:循環(huán)開始運(yùn)行時(shí),循環(huán)控制量的初始值(2)循環(huán)運(yùn)行條件:循環(huán)能否繼續(xù)重復(fù)的條件。

(3)循環(huán)增量:定義循環(huán)控制的量,每循環(huán)一次后按什么方式變化。循環(huán)引例的討論求均值的例子中,循環(huán)三要素分別是什么?循環(huán)體包括哪些語句?答:循環(huán)三要素分別如下。

(1)循環(huán)初始條件:輸入次數(shù)=0;

(2)循環(huán)運(yùn)行條件:輸入次數(shù)小于學(xué)生人數(shù);

(3)循環(huán)增量:輸入次數(shù)每次加1。

循環(huán)體語句包括:輸入學(xué)號(hào)、成績(jī)和累加成績(jī)。

循環(huán)的一般形式(1)循環(huán)增量可以放在循環(huán)體語句中。

(2)一般的循環(huán)形式如圖3.10所示(3)循環(huán)三要素中的一項(xiàng)、二項(xiàng)或者三項(xiàng),在某些情形下是可省略的。3.4.1當(dāng)型循環(huán)——while語句

while語句語法格式:

while(表達(dá)式)語句;

流程工作原理:這里的表達(dá)式是循環(huán)三要素中的“循環(huán)運(yùn)行條件”,而語句是循環(huán)體。只要表達(dá)式為真,則執(zhí)行循環(huán)體內(nèi)語句;否則終止循環(huán),執(zhí)行循環(huán)體后的語句。

至此,有讀者可能會(huì)注意到,循環(huán)三要素中的另外兩個(gè)要素并沒有顯式地體現(xiàn)出來,這需要我們?cè)谑褂脀hile結(jié)構(gòu)時(shí),自己按實(shí)際情形添加?!纠?-9】while語句的例子1

打印2、4、6、8、10。

【解】這是一個(gè)要循環(huán)輸出有規(guī)律變化數(shù)據(jù)的過程,輸出次數(shù)與輸出數(shù)據(jù)的關(guān)系如表3.21所示?!纠?-9】while語句的例子1答:將會(huì)造成首次打印值的不可預(yù)計(jì),打印的結(jié)果會(huì)出錯(cuò),且循環(huán)的次數(shù)不一定能控制在5次。

特別注意:循環(huán)結(jié)束時(shí),i的值為6,若循環(huán)后面的語句還需要使用i的值,需要清楚i當(dāng)前的值。若循環(huán)處理前沒有i=1的賦值,會(huì)出現(xiàn)什么情況呢?【例3-9】while語句的例子1【例3-9】while語句的例子1【例3-9】while語句的例子1

1 /*用while語句實(shí)現(xiàn)打印2、4、6、8、10*/

2 #include<stdio.h>

3

4 intmain()

5 {

6 inti=1;

7 while(i<6)

8 {printf("%d",2*i);

9 i++;

10 }

11 return0;

12 }

調(diào)試步驟參見書中內(nèi)容while語句特例情形

while(1)語句;當(dāng)while循環(huán)的條件表達(dá)式為1時(shí),循環(huán)如何運(yùn)行?

答:這要根據(jù)while的語法流程圖3.11來分析。表達(dá)式總為1,即為“真”,那么循環(huán)就一直執(zhí)行,永遠(yuǎn)不會(huì)停下來,這種情形也叫“死循環(huán)”。

沒有在while語句體中提供使“表達(dá)式”為假的動(dòng)作,通常這樣的循環(huán)將永不會(huì)終止,此為“無限循環(huán)”。死循環(huán):在編程中,一個(gè)無法靠自身的控制終止的循環(huán)稱為“死循環(huán)”或“無限循環(huán)”?!纠?-10】while語句的例子2讀程序分析結(jié)果:

1 intmain()

2 {

3 charc;

4

5 while((c=getchar())!='@')

6 {

7 putchar(('A'<=c&&c<='Z')?c-'A'+'a':c);

8 }

9 putchar('\n');

10 return0;

11 }

這個(gè)循環(huán)的三要素具體是什么?【例3-10】while語句的例子2程序的功能為:

(1)輸入字符若是大寫字母,則輸出對(duì)應(yīng)的小寫字母;否則原樣輸出。

(2)此過程可循環(huán)不斷地執(zhí)行下去,直到輸入字符@。答:(1)循環(huán)初始條件:c=getchar();

(2)循環(huán)運(yùn)行條件:c!='@';(3)循環(huán)增量:c=getchar()。

說明:此時(shí)的“循環(huán)增量”是循環(huán)控制量c接收鍵盤新輸入的一個(gè)字符,這也是循環(huán)控制量的一種變化方式?!纠?-11】while語句的例子3從鍵盤輸入8個(gè)學(xué)生的英語考試成績(jī)(成績(jī)?yōu)榘俜种频恼麛?shù)),輸出英語平均成績(jī)。

【例3-11】while語句的例子3

1intmain()

2{

3intcounter;/*計(jì)數(shù)器*/

4intgrade;/*分?jǐn)?shù)*/

5inttotal;/*總分*/

6intaverage;/*平均分*/

7

8/*初始化階段*/

9total=0;/*初始化total*/

10counter=0;/*初始化計(jì)數(shù)器*/

11/*處理階段*/

12while(counter<8)/*循環(huán)8次*/

13{

14 printf("Entergrade:");/*提示輸入*/

15 scanf("%d",&grade);/*讀入分?jǐn)?shù)*/

16 total=total+grade;/*將分?jǐn)?shù)加入總分*/

17 counter=counter+1;/*計(jì)數(shù)器加1*/

18}

19average=total/8;

20 /*輸出結(jié)果*/

21 printf("totalis%d\n",total);

22printf("averageis%d\n",average);

23return0;

24 }

為什么有的變量需要初始化,而有的不需要?

答:這是初學(xué)者不容易分清的問題。上述程序中,需要初始化的量有計(jì)數(shù)器counter和總分total,不需要初始化的量有分?jǐn)?shù)grade和均分average。需要初始化的變量的特點(diǎn)是,第一次被使用前,要有一個(gè)確定含義的值,因?yàn)樗旧淼闹禃?huì)影響到后續(xù)的計(jì)算結(jié)果,也就是首次是“讀操作”。不需要初始化的變量的特點(diǎn)是,首次使用是“寫操作”。首次是“讀操作”的變量必須做初始化的工作,首次是“寫操作”的變量則不必?!纠?-12】while語句的例子4

從鍵盤輸入若干個(gè)學(xué)生的英語考試成績(jī)(成績(jī)?yōu)榘俜种频恼麛?shù)),輸出英語平均成績(jī)。

【解】前面例子的循環(huán)三要素是確定的,見表3.27。在本例中,學(xué)生的人數(shù)沒有具體的數(shù)目,所以循環(huán)運(yùn)行的條件必須要重新設(shè)置,我們可以找一個(gè)不是正常成績(jī)值的數(shù)字作為輸入成績(jī)時(shí)的停止標(biāo)志,如“-1”,這樣,偽代碼可寫成表3.28所示的形式?!纠?-12】while語句的例子4【例3-12】while語句的例子4

對(duì)表3.28算法進(jìn)行測(cè)試要考慮哪幾類情形?

答:(1)正常情形:首次輸入的是分?jǐn)?shù)。

(2)異常情形:首次即輸入停止標(biāo)志,此時(shí),while循環(huán)的循環(huán)體語句不會(huì)執(zhí)行,計(jì)數(shù)器的值為0,求平均分時(shí),將會(huì)出現(xiàn)除以零的狀況,這是嚴(yán)重的邏輯錯(cuò)誤,它將會(huì)造成程序運(yùn)行失敗。

如果沒有初始化計(jì)數(shù)器或總和,那么程序結(jié)果可能會(huì)不正確。這是一個(gè)邏輯錯(cuò)誤?!纠?-12】while語句的例子4改進(jìn)后的算法【例3-12】while語句的例子4

1 /*計(jì)算平均分*/

2 #include<stdio.h>

3 intmain()

4 {

5 intcounter=0;/*計(jì)數(shù)器*/

6 intgrade;/*分?jǐn)?shù)值*/

7 inttotal=0;/*總分*/

8 floataverage;/*平均分?jǐn)?shù)*/

9

10 printf("Entergrade,-1toend:");

11 scanf("%d",&grade);/*首次讀取分?jǐn)?shù)*/

12

13 while(grade!=-1)/*-1為停止輸入標(biāo)志*/

14 {

15 total=total+grade;

16 counter=counter+1;

【例3-12】while語句的例子417 printf("Entergrade,-1toend:");

18 scanf("%d",&grade);/*讀取下一個(gè)分?jǐn)?shù)*/

19 }

20

21 if(counter!=0)

22 {

23 average=(float)total/counter;

24 printf("averageis%.2f\n",average);

25 }

26 else

27 {

28 printf("Nogradeswereentered\n");

29 }

30 return0;

31 }3.4.2直到型循環(huán)——do-while語句

do-while語句的語法格式:

do

語句;

While(表達(dá)式);這里的表達(dá)式是循環(huán)三要素中的“循環(huán)運(yùn)行條件”,程序進(jìn)入do-while循環(huán)后,先執(zhí)行循環(huán)體內(nèi)的語句,然后判斷表達(dá)式的真假,若為真則進(jìn)行下一次循環(huán),否則終止循環(huán)。該循環(huán)語句的特點(diǎn)是,表達(dá)式為假時(shí)也執(zhí)行一次循環(huán)體內(nèi)的語句。3.4.2直到型循環(huán)——do-while語句不論do-while的循環(huán)體包含幾條語句,建議都寫成如下的形式,以避免和while語句混淆

do

{

語句;/*循環(huán)體*/

}while(表達(dá)式);注意:上面do-while語句的寫法中,要注意和while語句的區(qū)別。例如:

while(表達(dá)式)——通常會(huì)被認(rèn)為是while語句的開始。

while(表達(dá)式);——可能會(huì)被誤讀成包含一條空語句的while?!纠?-13】do-while語句的例子1打印2、4、6、8、10。

while和do-while在很多時(shí)候也是可以相互替代的?!纠?-13】do-while語句的例子1【例3-13】do-while語句的例子1

while與do-while的比較do-while做了再說while判后再執(zhí)行這兩種循環(huán)的異同點(diǎn)如下:

(1)不同點(diǎn):while循環(huán)是在頂上測(cè)試循環(huán)終止條件,而do-while循環(huán)是在循環(huán)體之后,在底部進(jìn)行測(cè)試,所以循環(huán)體至少要執(zhí)行一次。

(2)相同點(diǎn):它們的循環(huán)三要素都是一樣的?!纠?-14】do-while語句的例子2

從鍵盤輸入整數(shù),當(dāng)輸入值比程序預(yù)設(shè)的值大時(shí)停止,顯示輸入的數(shù)字和次數(shù)。

【例3-14】do-while語句的例子2特例情形:當(dāng)首次輸入的整數(shù)num就比預(yù)設(shè)的值大時(shí),這個(gè)數(shù)字被輸出,計(jì)數(shù)器值為1?!纠?-14】do-while語句的例子2

1 /*do-while語句的例子2*/

2 #include<stdio.h>

3 #defineN25

4 intmain()

5 {

6 inti=0;

7 intnum;

8

9 do

10 {

11 scanf("%d",&num);

12 i=i+1;

13 printf("number=%d\n",num);

14 }while(num<=N);

15 printf("total=%d\n",i);

16 return0;

17 }

注意:do-while中的條件判斷和表3.34中退出循環(huán)的條件是相反的。

【例3-14】do-while語句的例子2用while來實(shí)現(xiàn)為了讓程序適合所有可能的情形,把while循環(huán)體內(nèi)的語句在while之前先執(zhí)行一次,這樣的程序顯然是不簡(jiǎn)潔的。

當(dāng)希望不管條件是否為假,循環(huán)體中的代碼都至少執(zhí)行一次時(shí),使用do-while循環(huán)比while方便而簡(jiǎn)潔。

3.4.3另一種當(dāng)型循環(huán)——for循環(huán)語句

for([表達(dá)式1];[表達(dá)式2];[表達(dá)式3])語句;for語句語法格式:for循環(huán)語句的執(zhí)行流程圖3.19

for([循環(huán)初始條件];[循環(huán)運(yùn)行條件];[循環(huán)增量])語句;while流程圖for流程圖3.4.3另一種當(dāng)型循環(huán)——for循環(huán)語句3.4.3另一種當(dāng)型循環(huán)——for循環(huán)語句說明:

(1)方括號(hào)[]表示三個(gè)表達(dá)式中的任何一個(gè)都可省略。

(2)循環(huán)初始條件:可以是一個(gè)或多個(gè)賦值語句,它用來給循環(huán)控制變量賦初值。

(3)循環(huán)運(yùn)行條件:是一個(gè)關(guān)系表達(dá)式,它決定什么時(shí)候退出循環(huán)。

(4)循環(huán)增量:定義循環(huán)控制變量每循環(huán)一次后按什么方式變化。for([循環(huán)初始條件];[循環(huán)運(yùn)行條件];[循環(huán)增量])語句;

把需要循環(huán)處理的問題中的循環(huán)三要素提煉出來,寫出for語句,就是很方便的事情了?!纠?-15】for語句的例子1打印2、4、6、8、10。

for(i=1;i<6;i++)printf("%d",2*i);

用for語句實(shí)現(xiàn)循環(huán)是一種相當(dāng)簡(jiǎn)潔的方式。

比較下面兩個(gè)程序段,各輸出什么結(jié)果?

(1)for(i=1;i<6;i++)printf("%d",2*i);

(2)for(i=1;i<6;i++);printf("%d",2*i);

【答】程序(1)就是例3-15,結(jié)果毋庸贅述;程序(2)的循環(huán)體只有一個(gè)分號(hào),所以是空語句,for循環(huán)結(jié)束后,i的值為6,故最后的結(jié)果是輸出12。把分號(hào)直接放在for部分的右側(cè),這使得for語句體成為一個(gè)空語句。通常情況下,這是邏輯錯(cuò)誤。【例3-16】for語句的例子2讀程序,給出程序功能及結(jié)果。

1 #include<stdio.h>

2 intmain()

3 {

4 intsum,i;

5 sum=0;

6

7 for(i=1;i<=100;i++)

8 {

9 sum=sum+i;

10 }

11 printf("%d",sum);

12 return0;

13 }

根據(jù)表3.38中sum迭代的變化規(guī)律,可以看出:

sum=1+2+3+…+100=5050【讀程經(jīng)驗(yàn)】

(1)我們可以用列表法把程序中關(guān)鍵的變量列出,在有循環(huán)時(shí),把循環(huán)控制量和迭代量的對(duì)應(yīng)變化逐步寫出,其實(shí)這也是程序單步跟蹤時(shí),我們看到的變量的變化過程。我們把這種變量變化的動(dòng)態(tài)過程記錄在表格中,使得動(dòng)態(tài)的每一步驟都“靜止”下來,這樣就可以仔細(xì)分析程序運(yùn)行的特點(diǎn)和規(guī)律,從而比較容易地得到程序的結(jié)果。

(2)在循環(huán)量較大時(shí),不一定要把每次迭代量具體計(jì)算出來,而是列出計(jì)算方法,這樣便于找到每次迭代和最終結(jié)果的關(guān)系。3.4.4無條件轉(zhuǎn)移——goto語句

goto語句標(biāo)號(hào);

goto語句也稱為無條件轉(zhuǎn)移語句,其作用是改變程序流向,轉(zhuǎn)去執(zhí)行語句標(biāo)號(hào)所標(biāo)識(shí)的語句。goto語句通常與條件語句配合使用,可用來實(shí)現(xiàn)條件轉(zhuǎn)移、構(gòu)成循環(huán)、跳出循環(huán)體等。語句標(biāo)號(hào)是按標(biāo)識(shí)符規(guī)定書寫的符號(hào),放在某一語句行的前面,標(biāo)號(hào)后加冒號(hào)(:)。

對(duì)于goto語句,有一種說法是,在結(jié)構(gòu)化程序設(shè)計(jì)中一般不主張使用goto語句,以免造成程序流程的混亂,使理解和調(diào)試程序都產(chǎn)生困難。

1974年,D.E.克努斯對(duì)于goto語句之爭(zhēng)作了全面公正的評(píng)述,其基本觀點(diǎn)是:不加限制地使用goto語句,特別是使用往回跳的goto語句,會(huì)使程序結(jié)構(gòu)難于理解,在這種情形下,應(yīng)盡量避免使用goto語句。但在另外一些情況下,為了提高程序的效率,同時(shí)又不至于破壞程序的良好結(jié)構(gòu),有控制地使用一些goto語句也是必要的,如跳出多重循環(huán)。

【例3-17】goto語句的例子打印2、4、6、8、10。

【解】程序流程見圖3.22,程序如下:

1 /*goto語句的例子*/

2 #include<stdio.h>

3 intmain()

4 {

5 inti=1;

6

7 loop:if(i<6)

8 {

9 printf("%d",2*i);

10 i++;

11 gotoloop;

12 }

13 printf("%d\n",sum);

14 return0;

15 }

3.4.5快速結(jié)束循環(huán)——break和continue語句

break和continue語句用于改變控制流,其作用是快速結(jié)束循環(huán),以減少不必要的運(yùn)算.【例3-18】break語句的例子1

在100以內(nèi)的整數(shù)中,求出最大的可被19整除的數(shù),要求用for語句實(shí)現(xiàn)。

【解】這是一個(gè)通過不斷循環(huán)測(cè)試整數(shù)是否滿足條件的過程:

(1)如果從整數(shù)i=1開始,只要i在100以內(nèi),i不斷加1并測(cè)試i%19是否為0,對(duì)于每一個(gè)找到的19的倍數(shù),我們都無法判斷是否在100內(nèi)是最大的;

(2)如果從整數(shù)i=100開始,只要i在100以內(nèi),i不斷減1并測(cè)試i%19是否為0,對(duì)于第一個(gè)找到的19的倍數(shù),就是所需要的值。

【例3-18】break語句的例子1【例3-18】break語句的例子1程序?qū)崿F(xiàn)如下:

1 /*break語句的例子*/

2 #include<stdio.h>

3 intmain()

4 {

5inti;

6 for(i=100;i>18;i--)

7 {

8 if((i%19)==0)break;

9 }

10 printf("%d\n",i);

11 return0;

12 }跟蹤調(diào)試參見書中內(nèi)容【例3-19】break語句的例子2找一個(gè)用3除余2,用5除余3,用7除余5的最小整數(shù),要求用for語句實(shí)現(xiàn)。

【解】這也是一個(gè)通過不斷循環(huán)測(cè)試整數(shù)是否滿足條件的過程:整數(shù)i從1開始,i不斷加1并測(cè)試其是否滿足題目要求的條件,滿足則跳出循環(huán),其中i的大小在什么范圍是未知的,所以循環(huán)條件是不確定的,這是和例3-18不同的地方。

循環(huán)運(yùn)行條件不確定,還能寫循環(huán)語句嗎?

答:回憶一下for的語法規(guī)則,即

for([循環(huán)初始條件];[循環(huán)運(yùn)行條件];[循環(huán)增量])語句;

其中,方括號(hào)[]表示三個(gè)表達(dá)式中的任何一個(gè)都可省略。題目的“循環(huán)運(yùn)行條件”不確定,也就是for中的此項(xiàng)可以省略,那么在實(shí)際的程序運(yùn)行中是怎么處理的呢?我們可以參看圖3.10所示的循環(huán)形式。缺少“循環(huán)運(yùn)行條件”的for循環(huán)和while(1)循環(huán)是等價(jià)的

“循環(huán)運(yùn)行條件”的菱形框沒有了,那么“循環(huán)體語句”和“循環(huán)增量”部分就形成了一個(gè)無條件的循環(huán)過程,相當(dāng)于“循環(huán)運(yùn)行條件”永遠(yuǎn)為真的情形,也就是“無限循環(huán)”。【例3-19】break語句的例子2【例3-19】break語句的例子2

1 /*break語句的例子2——用for實(shí)現(xiàn)*/

2 #include<stdio.h>

3 intmain()

4 {

5 inti;

6

7 for(i=1;;i++)

8 {

9 if(i%3==2&&i%5==3&&i%7==5)

10 {

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論