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