【C语言基础05】循环结构程序设计(含经典代码解析)
目錄
5.1 while語(yǔ)句
5.2 do-while語(yǔ)句
5.3 for語(yǔ)句
5.4 三種循環(huán)的比較
5.5 循環(huán)的嵌套
5.6 break語(yǔ)句和continue語(yǔ)句
5.7 綜合案例
循環(huán)結(jié)構(gòu)又稱(chēng)重復(fù)結(jié)構(gòu),是按照一定的條件重復(fù)執(zhí)行某段語(yǔ)句的程序控制結(jié)構(gòu)。
基本的循環(huán)結(jié)構(gòu):
??? 1)goto語(yǔ)句和if語(yǔ)句構(gòu)成的循環(huán)結(jié)構(gòu);
??? 2)while語(yǔ)句構(gòu)成的循環(huán)結(jié)構(gòu)
??? 3)do-while語(yǔ)句構(gòu)成的循環(huán)結(jié)構(gòu)
??? 4)for語(yǔ)句構(gòu)成的循環(huán)結(jié)構(gòu)
5.1 while語(yǔ)句
??? while語(yǔ)句用來(lái)構(gòu)成當(dāng)型循環(huán),多用于解決循環(huán)次數(shù)事先不確定的問(wèn)題。形式:
??? while(表達(dá)式)
??????? {
??????? ??? 循環(huán)體
??????? }
??? 功能:先判斷表達(dá)式值的真假,若為真(非零)時(shí),就執(zhí)行循環(huán)體;否則,退出循環(huán)結(jié)構(gòu)。
??? 例:編程實(shí)現(xiàn)1+2+3+4+……+100。
#include "stdio.h" main() {int a=1,sum;sum=0;while(a<=100){sum=sum+a;a++; }printf("%d",sum); }??? ① 從何處來(lái)
??? ② 到何處去
??? ③ 如何修改循環(huán)變量在
??? ④ 條件滿足做什么事情
??? 循環(huán)的初始值+循環(huán)條件+循環(huán)體+循環(huán)變量的增量+具有唯一真值的表達(dá)式
??? 注意:
??? 例:印數(shù)程序
#include "stdio.h" main() {int a=0;while(a<=1){a++;printf("%d\n",a);} }??? while(n++<=1);
??? n++為前綴式,先判斷n<=1,是否為真后,再加1;
??? 如果++n,則先再1,再判斷n<=1。
?? 例:輸入一行字符,按字母、數(shù)字、和其他分成三類(lèi),分別統(tǒng)計(jì)各類(lèi)字符的數(shù)目('\n’)不在統(tǒng)計(jì)范圍內(nèi)。
#include "stdio.h" #define IN 1 #define OUT 0 main() {int c,nl,nw,nc,state; //nc:字符數(shù) nl:行數(shù) //nw:字?jǐn)?shù) state=OUT;nl=nw=nc=0;printf("請(qǐng)輸入內(nèi)容并以ctrl+z為結(jié)束:\n");while((c=getchar())!=EOF) //不等于-1,即為真{++nc;if(c=='\n'){++nl;}if(c=='\t'||c==' '||c=='\n'){state=OUT;}else{if(state==OUT){state=IN;++nw;}}} printf("字符數(shù):%d\n",nc);printf("行 數(shù):%d\n",nl);printf("字 數(shù):%d\n",nw);return 0; }?解析: ??
??? 正文一行以'\n'為結(jié)束標(biāo)志;
??? 一個(gè)字以''為結(jié)束標(biāo)志的一串字符;
??? EOF是End Of File的意思,在C語(yǔ)言中定義的一個(gè)宏,用作文件結(jié)束標(biāo)志。從數(shù)值角度看,就是-1。從一個(gè)終端的輸入從來(lái)不會(huì)真的“結(jié)束”(除非設(shè)備被斷開(kāi)),但把從終端輸入的數(shù)據(jù)分區(qū)成多個(gè)“文件”卻很有用,因此一個(gè)關(guān)鍵的序列被保留下來(lái)來(lái)指明輸入結(jié)束
??? 行數(shù)統(tǒng)計(jì):對(duì)輸入中的'\n'字符進(jìn)行統(tǒng)計(jì);
??? 字?jǐn)?shù)統(tǒng)計(jì):對(duì)空格符''、制表符'\t'、換行符'\n'
??? 字符數(shù)統(tǒng)計(jì):對(duì)每個(gè)輸入的字符(不包含EOF)進(jìn)行計(jì)數(shù);
??? 算法:
??? (1)將標(biāo)志位state置為初值0,表示字符不在子字,各計(jì)數(shù)器變量均為0;
??? (2)讀一個(gè)字符c,如果不是EOF,則進(jìn)行:
??? ① 字符數(shù)+1;
??? ② 若c是行數(shù)則行數(shù)+1;
??? ③ 若c是空格符、換行符、制表符,則將標(biāo)志置為0,表示c字符不在字中;
??? 若c為非空白符,如果標(biāo)志位為0(表示c是字符的第一個(gè)字符)則將字?jǐn)?shù)+1,并修改標(biāo)志位為1(表示當(dāng)前字符c是一個(gè)字中的字符)
??? ④ 循環(huán)步驟2
??? ⑤ 如果c是EOF,則循環(huán)結(jié)束,轉(zhuǎn)步驟3
??? (3)輸出結(jié)果
??? 窮舉法:窮舉法的基本思想是根據(jù)題目的部分條件確定答案的大致范圍,并在此范圍內(nèi)對(duì)所有可能的情況逐一驗(yàn)證,直到全部情況驗(yàn)證完畢。若某個(gè)情況驗(yàn)證符合題目的全部條件,則為本問(wèn)題的一個(gè)解;若全部情況驗(yàn)證后都不符合題目的全部條件,則本題無(wú)解。窮舉法也稱(chēng)為枚舉法。
(1)順序列舉 是指答案范圍內(nèi)的各種情況很容易與自然數(shù)對(duì)應(yīng)甚至就是自然數(shù),可以按自然數(shù)的變化順序去列舉。
(2)排列列舉 有時(shí)答案的數(shù)據(jù)形式是一組數(shù)的排列,列舉出所有答案所在范圍內(nèi)的排列,為排列列舉。
(3)組合列舉 當(dāng)答案的數(shù)據(jù)形式為一些元素的組合時(shí),往往需要用組合列舉。組合是無(wú)序的。
? 從值域中取一個(gè)值,然后求其他兩個(gè)數(shù),滿足條件就是解答。
5.2 do-while語(yǔ)句
??? 直到型循環(huán),多用于循環(huán)次數(shù)事先不確定的問(wèn)題。
??? 形式:
??? do
??? {
??????? 循環(huán)體
??? }while(表達(dá)式);
??? 先執(zhí)行一次循環(huán)體,再判斷表達(dá)式的真假。若表達(dá)式為真(非0)則繼續(xù)執(zhí)行循環(huán)體,一直到表達(dá)式為假(0)時(shí)退出循環(huán)。
?? 注意:while后面的“;”號(hào)不能少。
?? while與do-while的比較
??? while:先判斷后執(zhí)行
?? do-while:先執(zhí)行后判斷,語(yǔ)句中的循環(huán)體至少要被執(zhí)行一次
? 當(dāng)while后面的表達(dá)式的第一次的值為真時(shí),兩種循環(huán)得到的結(jié)果相同;否則,二者結(jié)果不相同。
5.3 for語(yǔ)句
??? 可以用于循環(huán)次數(shù)已經(jīng)確定的情況,也可以用于循環(huán)次數(shù)不確定而給出了循環(huán)結(jié)束條件的情況。
??? 形式:
??? for(表達(dá)式1;表達(dá)式2;表達(dá)式3)
??? 循環(huán)體
執(zhí)行過(guò)程:
??? 先求解表達(dá)式1,再求解表達(dá)式2,若真(非0),則執(zhí)行for語(yǔ)句中指定的內(nèi)嵌語(yǔ)句,然后求解表達(dá)式3;若表達(dá)式2為假(0),則結(jié)束循環(huán);循環(huán)結(jié)束,執(zhí)行for語(yǔ)句下面的一條語(yǔ)句。
??? for(循環(huán)變量賦初值;循環(huán)條件;循環(huán)變量增值)
??? {
?? ? ?? 循環(huán)體;
??? }
??? 一般情況,等價(jià)于:
??? 表達(dá)式1;
??? while(表達(dá)式2)
??? {
??????? 語(yǔ)句
??????? 表達(dá)式3;
??? }
注意:
- 一般格式為(p1;p2;p3),p1可以省略,分號(hào)不能省略;如“for(;i<=100;i++)”,省略的p1必須在for前面給予確定,即省略前給初值。
- p2可以省略,但要保留分號(hào);這時(shí)無(wú)結(jié)束循環(huán)的條件,即循環(huán)不停地執(zhí)行下去,成為死循環(huán)。如“for(i=1,sum=0;;i++)sum=sum+i”,省略的部分必須在循環(huán)體中給出
- p3后面沒(méi)有分號(hào),也可以省略。省略時(shí),應(yīng)在循環(huán)體內(nèi)設(shè)置能改變循環(huán)變量值的語(yǔ)句,避免死循環(huán)。如“for(i=1,sum=0;i<=100;){sum=sum+i;i++}”
- 循環(huán)體可以是空語(yǔ)句,產(chǎn)生延時(shí)效果。如“for(i=0;i<5000;i++);”
- 雖然p1,p2,p3均能省略,但初學(xué)者不要嘗試
??? 例:求自然數(shù)前n項(xiàng)和。
#include "stdio.h" main() {int sum=0,i,n;printf("請(qǐng)輸入:");scanf("%d",&n);for(i=1;i<=n;i++){sum=sum+i;}printf("sum=%d",sum); }??? 例:從鍵盤(pán)輸入10個(gè)整數(shù),求平均值。
#include "stdio.h" main() {int i;float f,sum;for(i=0,sum=0.0; ;i++){scanf("%f",&f);sum+=f;if(f==0.0){break;}}if(i==0){printf("沒(méi)有數(shù)據(jù)!");}else{printf("%f",sum/i); }}??? 例:求2000至2050之間的閏年。
#include "stdio.h" main() {int i=2000;for(i;i<=2050;i++){if(i%4==0&&i%100!=0||i%100==0||i%400==0){printf("%d ",i);}}}? 例:兔子繁殖。斐波那鍥數(shù)列。
??? 算法分析:
??? ① 輸入繁殖的總時(shí)間
??? ② 繁殖的起始時(shí)間是3;1、2月數(shù)量是1
??? ③ 從3月直到n月結(jié)束,前兩個(gè)月的總數(shù)等于第三個(gè)月
??? 即f=f1+f2。輸出第三個(gè)月的數(shù)量即可。
#include <stdio.h> main() {int n; //月(總時(shí)間) long int f,f1,f2; //f=f1+f2int i=3; //3月開(kāi)始繁殖 起始月f1=1;f2=1;printf("請(qǐng)輸入月:");scanf("%d",&n);for(i;i<=n;i++){ f=f1+f2; //第3項(xiàng)=前兩項(xiàng)的和 f1=f2; //放第一個(gè)數(shù)字 f2=f; //放第二個(gè)數(shù)字 printf("%5ld",f); } }?? 例:放米粒。
??? 算法分析:
??? ① 循環(huán)變量初值n是0;sum作為存放器;t做為平方變量
??? ② n如果小于64,則向sum中放入數(shù),t再此基礎(chǔ)乘2,作為平方變量。
??? 注意:sum、t應(yīng)用double類(lèi)型,數(shù)據(jù)較大
#include "stdio.h" main() {int n; //循環(huán)變量 double sum,t;sum=0.0;t=1.0;for(n=0;n<64;n++){sum=sum+t;t=t*2; } printf("%e",sum);}5.4 三種循環(huán)的比較
- 一般情況下可相互代替
- while循環(huán)結(jié)構(gòu):
- 只設(shè)置了結(jié)束循環(huán)的條件,循環(huán)體內(nèi)需要設(shè)置打破循環(huán)條件而使循環(huán)趨向結(jié)束的語(yǔ)句。
- do-while循環(huán)和while循環(huán)相似,但do-while循環(huán)運(yùn)行循環(huán)體,然后再進(jìn)行循環(huán)結(jié)束條件的測(cè)試,循環(huán)體至少要執(zhí)行一次
- 對(duì)于已知重復(fù)次數(shù)的循環(huán),使用for結(jié)構(gòu)更加方便、清晰。
- 僅知道循環(huán)結(jié)束的條件,不知道循環(huán)次數(shù)的用while循環(huán)和do-while循環(huán)更簡(jiǎn)潔
5.5 循環(huán)的嵌套
算法分析:
例:求整數(shù)3~100中的素?cái)?shù)。
算法分析:
例:輸入一個(gè)字母,輸出由這個(gè)字母決定其高度的字符“金字塔”
算法分析:
- 外循環(huán)變量c1;并列內(nèi)循環(huán)變量c2
- 輸入字符如果是小寫(xiě),top置為a;大寫(xiě)top置為A;否則置為0
- top非0;打印圖形
- ?????? ① 外循環(huán)c1控制行數(shù);c1<=c,則輸出一行
- ?????? ② 內(nèi)循環(huán)輸出4個(gè)內(nèi)容:左邊所有的空格、一行前半段、一行后半段、換行
- ? ? ?? ③ c1=c1+1,繼續(xù)輸出下一行
- c1>c,則結(jié)束循環(huán)
注意:內(nèi)循環(huán)中的每一個(gè)for循環(huán),結(jié)束后都重新開(kāi)始。
#include "stdio.h" #include "ctype.h" main() {printf("請(qǐng)輸入字符:\n");char c,top,c1,c2;int i;top=isupper(c=getchar())?'A':(islower(c)?'a':'\0');if(top){for(c1=top;c1<=c;++c1){for(i=c;i>=c1+1;--i){putchar('-');}for(c2=top;c2<=c1;++c2){printf("%c",c2);}for(c2=c1-1;c2>=top;--c2){printf("%c",c2);}printf("\n");}} }例:打印輸出乘法表
算法分析:
- 輸出表頭部分:*、1-9、換行
- 輸出表體
??????? ① 外循環(huán)i控制行號(hào);初值為1,即外循環(huán)控制行數(shù)
??????? ② 如果i<=9,就輸出一行:
?????????? 輸出行號(hào)(被乘數(shù));
??? ?????? 列號(hào)j(乘數(shù))從1~9;如果j>=i則輸出i*j,否則輸出空格;
?????????? 換行;
??? ?????? 繼續(xù)循環(huán)
- 如果i>9就結(jié)束
??? 多重循環(huán)的使用:
- 給與循環(huán)有關(guān)的變量賦初值:只需執(zhí)行一次的賦初值操作,應(yīng)放在最外層循環(huán)開(kāi)始執(zhí)行之前。
- 對(duì)內(nèi)層循環(huán)的變量賦初值應(yīng)該放在內(nèi)層循環(huán)開(kāi)始執(zhí)行之前、外層循環(huán)的循環(huán)體內(nèi)
- 內(nèi)、外循環(huán)不能同名,否則將造成循環(huán)控制的混亂,導(dǎo)致死循環(huán)或計(jì)算結(jié)果錯(cuò)誤
- 正確的書(shū)寫(xiě):在內(nèi)循環(huán)中執(zhí)行的所有語(yǔ)句必須用{}括起來(lái)組成復(fù)合語(yǔ)句作為內(nèi)循環(huán)體;外層循環(huán)的語(yǔ)句應(yīng)放在內(nèi)循環(huán)體之外、外循環(huán)體之中
- 不應(yīng)在循環(huán)中執(zhí)行的操作應(yīng)放在進(jìn)入最外層循環(huán)之前或最外層循環(huán)結(jié)束之后
5.6 break語(yǔ)句和continue語(yǔ)句
break和continue語(yǔ)句一般將其放在if語(yǔ)句中
break語(yǔ)句:
遇到break語(yǔ)句。循環(huán)將無(wú)條件終止,程序跳出循環(huán)結(jié)構(gòu)。三種循環(huán)都可以使用break
break可跳出for{}循環(huán)
?
continue語(yǔ)句:
終止本次循環(huán),continue語(yǔ)句后面的語(yǔ)句不執(zhí)行而進(jìn)入下一次循環(huán)
break語(yǔ)句只能跳出一重循環(huán);
?
在while和do-while語(yǔ)句中,continue語(yǔ)句將使程序直接轉(zhuǎn)向條件測(cè)試處,當(dāng)為真是進(jìn)入下一輪循環(huán)。
在for語(yǔ)句中,將首先執(zhí)行循環(huán)控制變量的增值表達(dá)式,然后再判斷條件表達(dá)式,當(dāng)為真是進(jìn)入下一輪循環(huán)。
例:從鍵盤(pán)輸入任意個(gè)數(shù),求其平均值,當(dāng)輸入值為0時(shí),計(jì)算結(jié)束。
#include "stdio.h" main() {int i;float f,sum;for(i=0,sum=0.0; ;i++){scanf("%f",&f);sum+=f;if(f==0.0){break;}}if(i==0){printf("沒(méi)有數(shù)據(jù)!");}else{printf("%f",sum/i); }}例:用break語(yǔ)句打印九九乘法表
#include "stdio.h" main() {int i,j; //i控制行號(hào);j控制列for(i=1;i<=9;i++){for(j=1;j<=9;j++){if(i<j){break;}printf("%d*%d=%-4d",i,j,i*j);}printf("\n"); } }例:輸出100以內(nèi)能被7整除的數(shù)。
#include "stdio.h" main() {int i,j;for(i=1;i<=100;i++){if(i%7!=0){continue;}printf("%4d",i);} }5.7 綜合案例
列舉算法
根據(jù)提出的問(wèn)題,列舉所有可能的情況,并根據(jù)條件檢驗(yàn)?zāi)男┦?/span>需要的,哪些是不需要的。關(guān)鍵是根據(jù)問(wèn)題的性質(zhì)確定判定的條件,從而對(duì)列舉的所有條件進(jìn)行判斷。
試探算法
列舉量事先不知,只能從初始情況開(kāi)始,往后逐步進(jìn)行試探,直到滿足給定的條件為止。
#include "stdio.h" main() {int n,flag,x,k,a,b,c,d,e; //k是孩子;abced是五個(gè)小孩分到的蘋(píng)果 n=11; //n是蘋(píng)果 flag=1;while(flag){x=n;flag=0;for(k=1;k<=4&&flag==0;k++){if((n+1)%(k+1)==0){n=n-(n+1)/(k+1);}else{flag=1;}}if(flag==0&&n!=11){flag=1;}n=x+1;} printf("總蘋(píng)果:%d\n",x);a=(x+1)/2;b=(x-a+1)/3;c=(x-a-b+1)/4;d=(x-a-b-c+1)/5;e=11;printf("A=%d\n",a);printf("B=%d\n",b);printf("C=%d\n",c);printf("D=%d\n",d);printf("E=%d\n",e);}- 假設(shè)蘋(píng)果的數(shù)量為x,設(shè)5個(gè)小孩分蘋(píng)果的數(shù)為a,b,c,d,e?? a=(x+1)/2;b=(x-a+1)/3…
- 設(shè)當(dāng)前試探點(diǎn)蘋(píng)果數(shù)量為n:第k個(gè)小孩得到全部剩下蘋(píng)果的:(k+1)/1+k(k+1)/1 ;即(n+1)/(k+1)個(gè)蘋(píng)果。可被整除。
- 發(fā)完第k個(gè)小孩后,剩下的蘋(píng)果為n-(n+1)/(k+1)=>n
- 進(jìn)行4次分配,如果每次分配時(shí)均滿足其中的條件,并且剩下11個(gè)蘋(píng)果,則試探的n即為原來(lái)的蘋(píng)果數(shù)x。
- while循環(huán)進(jìn)行試探,for循環(huán)模擬4次的發(fā)放。
- 當(dāng)4次模擬條件均滿足,且最后剩下11個(gè)蘋(píng)果,則當(dāng)前試探的n即為原來(lái)的蘋(píng)果數(shù)x5
密碼問(wèn)題
#include "stdio.h" main() {char c;int k;printf("請(qǐng)輸入k的值:");scanf("%d",&k);getchar();c=getchar();while(c!='\n'){if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){c=c+k;if(c>'z'||(c>'z'&&c<='z'+k)){c=c-26;}}printf("%c",c);c=getchar();}}?
?
總結(jié)
以上是生活随笔為你收集整理的【C语言基础05】循环结构程序设计(含经典代码解析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pointofix 全局快捷键_Poin
- 下一篇: 风雨小记:成长