




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- T-ZZB 1584-2023 低壓電源系統(tǒng)的電涌保護(hù)器(SPD)
- 二零二五年度專業(yè)技術(shù)師徒傳承合作合同
- 2025年度門店合作線上線下融合營(yíng)銷協(xié)議
- 二零二五年度不占股份分紅權(quán)益共享協(xié)議
- 二零二五年度招商引資合同中的政府與企業(yè)合作模式創(chuàng)新
- 2025年度終止供貨協(xié)議函范文模板與簽訂程序指導(dǎo)
- 二零二五年度綠色建筑產(chǎn)業(yè)廠房租賃服務(wù)協(xié)議
- 二零二五年度勞動(dòng)合同法未簽訂合同員工競(jìng)業(yè)禁止協(xié)議
- 二零二五年度物業(yè)安全管理人員勞動(dòng)合同范本
- 二零二五年度消防安全設(shè)施設(shè)備安全評(píng)估與整改服務(wù)合同
- 七年級(jí)下冊(cè)《平行線的判定》課件與練習(xí)
- 修高速土方合同范例
- 2024年形勢(shì)與政策復(fù)習(xí)題庫(kù)含答案(綜合題)
- 江蘇省南通市2025屆高三第一次調(diào)研測(cè)試數(shù)學(xué)試題(南通一模)(含答案)
- DCMM數(shù)據(jù)管理師練習(xí)測(cè)試卷
- 油氣行業(yè)人才需求預(yù)測(cè)-洞察分析
- 檢修安全知識(shí)培訓(xùn)課件
- 學(xué)校心理健康教育存在的問題及改進(jìn)措施
- 合成生物學(xué)研發(fā)平臺(tái)與年產(chǎn)200噸合成生物制品項(xiàng)目可行性研究報(bào)告寫作模板-申批備案
- 2025年品控部工作計(jì)劃
- 《交通運(yùn)輸概論》課件
評(píng)論
0/150
提交評(píng)論