《第6章循環(huán)控制》由會員分享,可在線閱讀,更多相關(guān)《第6章循環(huán)控制(43頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、第第6章章 循環(huán)控制循環(huán)控制6.1 概述概述問題1:假如全班41人,欲從鍵盤上輸入每人的數(shù)學(xué)成績,然后計算出平均成績;問題2:編程計算n!。重復(fù)執(zhí)行一組語句是程序設(shè)計要求的基本語言功能之一。在C語言中可以用以下語句來實現(xiàn)循環(huán):(1)if 和 goto(2)while(3)do-while(4)for6.2 goto語句以及用goto語句構(gòu)成循環(huán)n語法:goto label;n其中:label是語句標(biāo)號,它命名的規(guī)則同變量名;n語義:使程序無條件地轉(zhuǎn)向標(biāo)號為label的語句去執(zhí)行;n如:用if語句構(gòu)成循環(huán),求sum=1+2+100 main()int i=1,sum=0;loop:if(i=10
2、0)sum=sum+i;i+;goto loop;printf(“%d”,sum);n說明:(1)標(biāo)號不必進(jìn)行類型說明;(2)程序中的任何一個語句均可帶上標(biāo)號,但標(biāo)號必須以冒號結(jié)束;(3)不提倡使用goto語句。6.3 while語句n語法:while(exp)循環(huán)體語句;n語義:當(dāng)exp為真時,執(zhí)行循環(huán)體,為假時,執(zhí)行循環(huán)語句的后續(xù)語句;n如:用while語句構(gòu)成循環(huán),求sum=1+2+100。i1,sum 0當(dāng)i小于等于100 sum=sum+i i=i+1輸出suml程序如下:lmain()int i=1,sum=0;while(i=100)sum+=i;i+;printf(“%d”,s
3、um);(2)循環(huán)體語句多于一個時,必須用復(fù)合語句;說明:(1)在while語句中(exp)應(yīng)有確定的值,以確保循環(huán)的正常開始;(3)循環(huán)體內(nèi)應(yīng)有改變循環(huán)控制變量的語句,以確保循環(huán)進(jìn)行有限次后正常結(jié)束;如:i=1;while(i=100)sum=sum+1;(死循環(huán))(4)while 循環(huán)的特點是先判斷后執(zhí)行,故循環(huán)有可能一次都不被執(zhí)行;int n=0;while(n+=2);printf(“%d”,n);如:i=3;while(i0)m=n/10;l=n-m*10;printf(%ld,l);n=m;k+;printf(nk=%ld,k);例:給一個正整數(shù),按逆序打印出各位數(shù)字,并求出它是幾
4、位數(shù)。輸入:230876輸出:6,7,8,0,3,2,k=6關(guān)鍵6.4 do-while語句n語法:do 循環(huán)體語句;while(exp)n語義:當(dāng)exp為真時,執(zhí)行循環(huán)體,為假時,執(zhí)行循環(huán)語句的后續(xù)語句;n如:用do-while語句構(gòu)成循環(huán),求sum=1+2+100 i1,sum 0 sum=sum+i i=i+1當(dāng)i小于等于100輸出suml程序如下:main()int i=1,sum=0;do sum+=i;i+;while(i10)循環(huán)被執(zhí)行了一次6.5 for循環(huán)語句n語法:for(exp1;exp2;exp3)循環(huán)體語句;n語義:n 如:for(i=1;i=100;i+)sum=s
5、um+i;n 可看成:n for(循環(huán)變量賦初值;循環(huán)條件;循環(huán)變量增值)語句;n說明:-(1)顯然for循環(huán)更簡潔,更靈活;-(2)循環(huán)體可以是復(fù)合語句;-(3)for語法中的三個表達(dá)式均可以是逗號表達(dá)式,故可同時對多個變量賦初值及修改。-如:for(i=0,j=1;jn&In;i+,j+)-(4)for語句中三個表達(dá)式可省:8 省exp1;如:i=1;for(;i5;i+)printf(“%dn”,i);等價于 for(i=1;i5;i+)printf(“%dn”,i);8 省exp3;如:for(i=1;i5;)printf(“%dn”,i);i+;等價于 for(i=1;i5)brea
6、k;8 三個表達(dá)式全省時,如:for(;)語句;等價于 while(1)語句;(5)for語句中的循環(huán)體可以是空語句;如:for(k=1,s=0 ;k5;s=s+k,k+);printf(“%dn”,s);6.6 循環(huán)的嵌套三種循環(huán)可以互相嵌套;例:打印九九乘法表main()int i=1,j=1;for(;i=9;i+)for(j=1;j=9;j+)printf(“%d*%d=%2d “,i,j,i*j);printf(“n”);說明:(1)內(nèi)循環(huán)必須完全包含在外循環(huán)中,不能交叉;(2)并列循環(huán)允許使用相同的循環(huán)變量,嵌套循環(huán)不允許使用相同的循環(huán)變量k作循環(huán)變量k作循環(huán)變量n作循環(huán)變量(3)
7、允許使用break或goto語句將循環(huán)控制從循環(huán)體內(nèi)轉(zhuǎn)到循環(huán)體外,也可以用continue語句將控制在循環(huán)體內(nèi)轉(zhuǎn)移,但不允許用任何方式從循環(huán)體外轉(zhuǎn)到循環(huán)體內(nèi);6.8 break語句和語句和continue語句語句l6.8.1 kreak語句形式:break;作用:(1)跳出switch語句;(2)從循環(huán)體內(nèi)跳出循環(huán)體;while(e1).if(e2)break;.e1e2假真真break(3)在多重循環(huán)中,break只能退出其所在循環(huán)。(4)break只能用在循環(huán)語句、switch語句中,它的功能是強(qiáng)行退出循環(huán)或switch;break;l6.8.2 continue語句 形式:continu
8、e;作用:結(jié)束本次循環(huán),跳過其后循環(huán)體內(nèi)語句,進(jìn)行下一次循環(huán)判斷。While(e1).if(e2)continue.假e1e2真真continue例:下列程序運行的結(jié)果是?main()int n;for(n=20;n30;n+)if(n%4!=0)continue;printf(“%5d ”,n);結(jié)果為:20 24 28 例1:計算:分析:(1)這里的積分采用梯形法計算,梯形積分計算公式是:#include#include main()int n,i;float x,h,xi,sum;scanf(“%f%d”,&x,&n);h=x/n;sum=(1.0+exp(-x*x/2)/2;xi=h;
9、for(i=1;i=n-1;i+)sum+=exp(-xi*xi/2);xi+=h;sum=0.5+h*(1.0/sqrt(2.0*3.14)*sum;printf(“n%fn”,sum);TF輸入xx=1.0e-6 s1=s2 s2=0.5*(s1+x/s1)s3=s2-s1輸出s2 分析:解決該問題的N-S圖如右:例2:用牛頓迭代法求x的平方根。牛頓迭代公式為:#include#include main()float x,s1=1;s2=1,s3;scanf(“%f”,&x);if(x=1.0e-6)s1=s2;s2=0.5*(s1+x/s1);s3=s2-s1;printf(“nsqrt
10、(%f)=%fn”,x,s2);例3:統(tǒng)計輸入的行數(shù)、單詞的個數(shù)(設(shè)單詞是一個不包含任何空白字符的字符序列)以及輸入的總的字符個數(shù)。分析:(1)設(shè)變量nl、nw、nc分別表示輸入的行數(shù)、單詞的個數(shù)和輸入的總字符數(shù),初值均為0;(2)對于nl,每輸入一個n增1,對于nc,每輸入一個字符,增1,而對于nw,只有當(dāng)輸入的字符為非空白字符、非回車且前一個字符為空或回車時才增1;(3)設(shè)計變量inword,當(dāng)其值0時,表示當(dāng)前字符的前一字符為空白或回車,當(dāng)其值為1時,表示當(dāng)前字符的前一字符非空或回車,此當(dāng)前字符仍為該單詞中的內(nèi)容;(4)inword的初始值為0;(5)故nw增1的條件是:當(dāng)前字符非空白或
11、回車且inword=0;#define YES 1#define NO 0#include main()int c,nl,nw,nc,inword;inword=NO;nl=nw=nc=0;while(c=getchar()!=#)+nc;if(c=n)+nl;if(c=|c=n|c=t)inword=NO else if(inword=NO)inword=YES;+nw;printf(“nl=%d nw=%d nc=%dn”,nl,nw,nc);例4:對于-5x11;-10y9;-6z18,求方程:x3+y3+z3=3的全部整數(shù)解。分析:(1)程序設(shè)計有三種基本思維方法:枚舉法、歸納法、抽象
12、法。該題是典型的枚舉法;(2)枚舉法:就是逐一列舉出可能解的各個元素,并加以判斷,直到求得所需要的解。常用在排列、組合、數(shù)據(jù)分類、信息檢索、多解方程的求解上;(3)使用枚舉法,必須掌握兩條原則:確定搜索的范圍(這個范圍必須是有限的);選擇枚舉的策略(按照一條什么樣的路徑來逐一枚舉);這兩條原則使用得好壞,對程序的工作量有巨大的影響。程序如下:#include main()int x,y,z;for(x=-5;x12;x+)for(y=-10;y10;y+)for(z=-6;z19;z+)if(x*x*x+y*y*y+z*z*z=3)printf(“%5d%5d%5dn”,x,y,z);例5:百
13、錢百雞問題。用100元錢買100只雞,每只公雞5元,每只母雞3元,每3只小雞1元,要求每種雞至少買一只,且必須是整只的,問各種雞各買多少只?分析:(1)這是一個組合問題,歸根到底是求三元一次方程的一組解;(2)設(shè) i,j,k分別表示公雞、母雞和小雞的只數(shù)。為了確定i,j,k的取值范圍,可以有不同方法。不同的方法,程序的計算量相差甚遠(yuǎn);(3)方法一:i:1 20;j:1 33;k:1100;(4)方法二:i:1 18;j:1 31;k:100ij;(5)方法三:由i+j+k=100及5i+3j+k/3=100得14i+8j=200,由此可得:i:1 13;j:1 23;k=100ij;(6)方法
14、四:由方法三中的14i+8j=200得7i+4j=100可得:i:1 13;j=(100 7 i)/4;k=100ij;main()int i,j,k;for(i=1;i=20;i+)for(j=1;j=33;j+)k:=100-i-j;if(i*5+j*3+k/3=100)printf(“k=%d,j+%d,i=%dn”,k,j,i);例6:求整數(shù)a和b的最小公倍數(shù)。分析:(1)如果 i 是a 和b的最小公倍數(shù),則 i 必能被 a 和 b 整除,同時 i 必須是自然數(shù),所以其取值范圍是;(2)方法一:i 從1開始,依次增加,直到第一個能被a和b整除為止,這個 i 就是a和b的最小公倍數(shù);(3
15、)方法二:令從i 從a開始,并使 i 每次增加a而不是增加1,這就保證了 i 總是a的倍數(shù)。故每次只要判斷 i 能否被b整除就可以了。一旦判斷成立,i 就是a和b的最小公倍數(shù);程序一:#include main()int a,b,i;scanf(“%d%d”,&a,&b);i=0;while(1)i+;if(i%a=0)if(i%b=0)printf(“%dn”,i);break;程序二:#include main()int a,b,i;scanf(“%d%d”,&a,&b);i=0;while(1)i+=a;if(i%b=0)printf(“%dn”,i);break;例7:猴子第一天摘下若
16、干桃子,當(dāng)即吃了一半,還不過癮,又多吃了一個。第二天早上又將剩下的桃子吃掉了一半,又多吃了一個,以后每天早上都吃了前一天剩下的一半零一個。到第10天早上再想吃時,發(fā)現(xiàn)只剩下一個桃子了。求第一天共摘多少個桃子。分析:(1)歸納法,是從大量的特殊性中總結(jié)出規(guī)律性或一般性的結(jié)論。(2)歸納,在程序設(shè)計上主要表現(xiàn)為遞歸和迭代。我們常常用遞歸和迭代的方式把一個復(fù)雜的計算過程化為簡單過程的多次重復(fù),這種重復(fù)很容易用循環(huán)來實現(xiàn);(3)在本例中,假設(shè) s 為剩下的,則s+1為前一天的一半,而2(s+1)為前一天的總個數(shù)。依次類推,10天前的桃子數(shù)即可算出;(4)歸納法的另一重要用途是用于數(shù)列和級數(shù)求和;Sn=
17、(Sn+1+1)*2程序如下:main()int s,i;s=1;for(i=1;i=9;i+)s=(s+1)*2;printf(“s=%dn”,s);例8:有一張足夠大的紙,厚0.09毫米,問將它對折多少次后可以達(dá)到珠穆朗瑪峰的高度(8848米)?分析:(1)采用歸納法;(2)設(shè)a為高度,初值為910-5米;(3)對折后,高度為前一次高度的2倍,每次乘2后判斷乘積是否已超過8848米。若已超過,則記下乘2的次數(shù)就是對折的次數(shù);(4)請讀者自己編程;例9:用循環(huán)語句打印下列圖案:*分析:(1)這是一個典型的循環(huán)嵌套問題;(2)該圖案中一共有6行,打印時需一行一行進(jìn)行,設(shè)正在處理的行為第 i 行,則 i 從1 6;(3)每行的字符個數(shù)與所在行有關(guān),設(shè)j表示第 i 行第j個字符,則j從 1 2*i 1;(4)每行的起始位置。設(shè)第一行為第20列的話,則第 i 行的位置可用21-i 來表示。程序如下:main()int i,j;for(i=1;i=6;i+)for(j=1;j=20-i;j+)printf(“”);for(j=1;j=2*i-1;j+)printf(“*”);printf(“n”);例10:用循環(huán)語句打印下列圖案:*分析:(1)將該圖案分成上下兩部分處理;(2)定行、定行中的字符個數(shù)、定每行打印的起始位置。6.7 幾種循環(huán)的比較幾種循環(huán)的比較lP.114 自學(xué)