C語言第5章循環結構程序設計課件_第1頁
C語言第5章循環結構程序設計課件_第2頁
C語言第5章循環結構程序設計課件_第3頁
C語言第5章循環結構程序設計課件_第4頁
C語言第5章循環結構程序設計課件_第5頁
已閱讀5頁,還剩175頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第五章循環結構程序設計§5.1概述前面已介紹了順序結構,選擇結構,本章介紹循環結構。如:

sum=1+2+3+…+100;實際問題:一組重復執行的語句。第五章循環結構程序設計§5.1概述前面已1則用循環結構解決。C語言用四種形式循環2.do-while語句3.For語句4.break、continue和goto語句1.

While語句則用循環結構解決。C語言用四種形式循環2.do-whi2§5.2while語句

while語句在C語言中用得比較多,它是通過判斷循環控制條件是否滿足來決定是否繼續循環,又稱“當型”循環。形式:while(表達式) 循環體語句2.執行過程:先判斷表達式的值。若0.則執行其后面的語句,否則while執行完畢。專門的當型循環語句––while語句§5.2while語句while語句在C語言中33.流程圖:表達式語句0=0下一語句將上述例子用while語句寫出while(i<=100){sum+=i;i++;}3.流程圖:表達式語句0=0下一語句將上述例子用whil4語句中應有使表達式=0的語句。否則會出現無限循環–––"死"循環。注:

while后面的語句一般為復合語句,即:加{}語句中應有使表達式=0的語句。注:while后面的5 我們來看下面的例子 例5.1寫一個程序,輸入一個班學生的成績,求全班的平均成績。 分析:輸入成績、計算平均成績都是一個重復性過程,因此可以用循環語句來實現。在這里,我們并不知有多少個學生,也就是說不知循環到底有多少次,但考慮到成績沒有負數,這樣就可以把循環條件定為:每當輸入的分數大于等于0時就繼續輸入成績;輸入的分數小于0時就停止輸入。 我們來看下面的例子6 解題步驟如下: (1)輸入一個分數 (2)當“分數>=0”時,做下列工作: ①累計總分; ②人數加一; ③輸入下一分數; (3)重復第(2)步,直到“分數<0”。 程序: #include<stdio.h> main() { floatscore,average=0; /*average存放平均成績,初值為0*/ 解題步驟如下:7intn=0; /*n用來存放學生數,初值為0*/scanf(″%f″,&score); /*輸入第一個學生的分數*/while(score>=0){average+=score; /*average先用來放總分*/n++; /*學生數增一*/scanf(″%f″,&score);/*輸入下一個學生的分數*/}intn=0; /*n用來存放學生數,初值為0*/8if(n!=0)average=average/n; /*求平均成績,average*/printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/}

在使用while語句的時候,我們要注意以下兩個問題:(1)循環體如果包含一個以上的語句,應該用花括號括起來,以復合語句的形式出現。如果不加花括號,則while語句的范圍只到while后面的第一個分號處。比如上例中,while語句中如無花括號,則while語句范圍只到“average+=score;”。if(n!=0)average=average/n; 9(2)在循環體中應有使循環趨向于結束的語句。比如上例中,循環結束的條件是“score>=0”,那么當我們把這個班的成績全部輸入完后,一定要輸入一個負數,才能使程序往下執行。(3)循環體語句有可能一次也不執行。比如說上例中,當第一次輸入的分數就為負數時,則循環體一次也不執行。(2)在循環體中應有使循環趨向于結束的語句。比如上例中,循環10§5.3do…while語句do-while語句的特點是: 先執行循環體中的語句,再通過判斷表達式的值來決定是否繼續循環,循環條件的測試是在循環的尾部進行的。它是一種專門的“直到型”循環語句。它的一般形式為:do循環體語句 while(表達式);§5.3do…while語句do-while語句的特點是11語句表達式0=03.流程:語句表達式0=03.流程:12對于例5.1用do-while語句編寫程序如下:#include<stdio.h>main(){floatscore,average=0;intn=0;do{ /*不進行判斷,先進入循環*/scanf(″%f″,&score); /*輸入學生的分數*/

對于例5.1用do-while語句編寫程序如下:13if(score>=0){average+=score;n++; }}while(score>=0); /*表達式為非0,則繼續*/if(n!=0)average/=n; /*求平均成績,average*/printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/}if(score>=0)14 例5.2編程序求1+3+5+7+9+…這樣的數之和。如果累加數大于750時,則程序終止并輸出結果。 main(){ inti=1,sum=0; while(sum<=750) {sum=sum+i;i=i+2; }printf("\n%d",sum); } 例5.2編程序求1+3+5+7+9+…這樣的數之和。如15 例5.3用do-while語句求1至1000之間滿足“用3除余2,用5除余3,用7除余2”的數,且一行只打印五個數。 分析:判斷一個數被另一個數除,用取模運算%。三個條件是“與”的關系。一行打印五個數,可以通過計數到5再回車換行。 程序代碼如下: #include<stdio.h> main() { inti=1,j=0; do { 例5.3用do-while語句求1至1000之間滿足“16if(i%3==2&&i%5==3&&i%7==2){printf(″%4d″,i);j=j+1;if(j%5==0)printf(″\n″);}i=i+1;}while(i<1000);}注意: 1、do-while語句的循環體語句至少要被執行一次,因為它是進入循環后再判別表達式。而while語句卻是首先判別表達式,如果表達式值為0,則一次循環也不執行。if(i%3==2&&i%5==3&&i%7==2)172、循環控制變量必須在循環體內有所改變,才能使while和do-while語句的循環控制條件表達式的值不斷改變,直至循環結束。否則會造成死循環。例如: i=1; while(i<=100) putchar(′*′); i++; 這個循環永遠不會結束,因為“i++;”語句不屬于循環體中的語句,循環控制變量i沒有在循環體內被改變。程序應該作如下改變:2、循環控制變量必須在循環體內有所改變,才能使while和d18 i=1; while(i<=100) { putchar(′*′); i++; }這條循環語句執行的結果是輸出100個“*”。還可以將它改成do-while語句: i=1; do{ putchar(′*′); i++; }while(i<=100); i=1;19 大家可以看到,對于同一個問題,既可以用while語句處理,也可以用do-while語句處理。那么,它們到底有什么區別呢?

while語句與do…while語句的區別:

當第一次執行時,若表達式=0時,則while語句與dowhile有所不同,dowhile執行一次后面的語句,而while不執行。 大家可以看到,對于同一個問題,既可以用while語句處理,20§5.3for語句1.一般形式首先計算表達式1,接著執行表達式2,若表達式2的值0,則執行語句,接著計算表達式3,再判斷表達式2的值.依此重復下去,直到表達式2的值=0(假)。for語句是C語言中最有特色的循環語句,使用最為靈活方便。for(表達式1;表達式2;表達式3) 循環體語句§5.3for語句1.一般形式首先計算表212.流程:計算表達式1求表達式2值語句計算表達式3=0(假)0(真)2.流程:計算表達式1求表達式2值語句計算表達式3=0(假222.執行過程(1)先求解表達式1。(2)求解表達式2,若其值為真(值非0),則執行for語句中指定的循環體語句,然后執行下面第(3)步。若為假(值為0),則結束循環,轉到第(5)步。(3)求解表達式3。(4)轉回上面第(2)步繼續執行。(5)循環結束,執行for語句下面的一個語句。2.執行過程23用for語句寫出上述例子for用while代替的流程表達式1;while(表達式2){語句表達式3;}for(i=1;i<=100;i++)sum+=i;for語句完全可以用while代替,但for直觀、簡單、方便用for語句寫出上述例子for用while代替的流程for24for語句中的各表達式含義(1)表達式1:初值表達式,用于在循環開始前,為循環變量設置初始值。(2)表達式2:循環控制邏輯表達式,它控制循環執行的條件,決定循環次數。(3)表達式3:循環控制變量修改表達式,定義了循環一次,循環控制變量的變化情況。注意:①表達式1,表達式2,表達式3必須用分號隔開②只要條件為真,for循環就一直執行,一旦條件變為假,程序就從緊跟在for循環后面的語句重新開始執行。循環體語句:被重復執行的語句。for語句中的各表達式含義25下面通過一個例子來看for語句的執行過程。例5.4在屏幕上打印1到100的數字。當然解決這個問題我們可以用100個printf語句實現,但當要打印的數字量很大時,采用這種方式顯然是不合適的,我們可以用for循環語句來實現。程序如下:#include<stdio.h>main(){intx;for(x=1;x<=100;x++)printf(″%d″,x);}下面通過一個例子來看for語句的執行過程。26在這個程序中,x經初始化置為1,因為x小于100,調用printf語句x+1,并且測試x,看其是否仍然小于或等于100。重復進行這個過程,直到x大于100,循環結束。在這個例子中,x是循環控制變量:循環每重復一次x發生變化,并對x進行檢查。C語言第5章循環結構程序設計課件27例5.5寫程序計算s=1+2+3+…+100分析:此題可用循環語句來編寫程序,循環控制變量i從1增加到100。設s的初值為0,則循環體為: s=s+i; /*i=l,2,…,100*/程序:#include<stdio.h>main(){ints=0,i;for(i=l;i<100;i++)s=s+i; /*循環體語句*/printf(″s=%d″,s);}例5.5寫程序計算s=1+2+3+…+10028上面程序中,for語句的執行過程為:①計算表達式1“i=l;”,得到循環控制變量的初值;②求解表達式2,若表達式2的值為零(當x>100),則結束for循環;③執行循環體語句“s=s+i;”;④求解表達式3,“i++;”,然后轉向步驟②。上面程序中,for語句的執行過程為:29 對于for循環,有一點非常重要,即條件測試永遠是在循環開始時進行,如果在循環開始時條件為假,那么循環體語句就不會被執行。如: inti=10; for(k=10;k!=i;k++)printf(″%d″,k); printf(″%d″,k); 在這個循環程序段中,循環開始時,由于i=k,所以根本不會執行,正是由于條件表達式取值為假,循環體語句和循環的增量部分都不執行,因此,k一直為10,最后屏幕上輸出的數字也是10。 對于for循環,有一點非常重要,即條件測試永遠是在循環開30例5.6寫程序計算s=1-3+5-7…-99+101。 這個例子也可看成是數的累加,但與上面的例子稍有差別,就是相加的數一個為正數,一個為負數。程序代碼如下:#include<stdio.h>main(){inti,t=1,s=0;for(i=1;i<=101;i+=2){t=t*i;例5.6寫程序計算s=1-3+5-7…-99+101。31s=s+t;t=(-t)/i; /*正1,負1交叉*/}printf(″%d\n″,s);}s=s+t;32for語句與while語句的比較for語句等價于下列語句序列: 表達式1; while(表達式2) {語句; 表達式3; }相比之下,for語句顯得結構整齊、緊湊、清晰。for語句與while語句的比較33

for語句的變形1.表達式的省略 如果在for語句之前給循環變量賦了初值,則表達式1可以省略,但其后的分號不可省略。 對于例5.2,其循環語句可以寫成如下形式: i=1; /*在for語句之前給循環變量賦初值*/ for(;i<=100;i++) s=s+i;如果省略表達式3,則應在for語句的循環體內修改循環控制變量。for語句的變形34例如:for(i=1;i<=100;){s=s+i;i++; /*修改循環控制變量*/}例如:35如果表達式1和表達式3都省略,則for語句就相當于while語句。例如: i=l; /*for語句之前給循環變量賦初值*/ for(;i<=100;) { s=s+i; i++; /*修改循環控制變量*/ }如果表達式1和表達式3都省略,則for語句就相當于while36就相當于: i=1; while(i<=100) { s=s+i; i++; }就相當于:37如果三個表達式都省略,則for是無循環終止條件的循環,因此有可能形成無限循環,如下例所示: for(;;)printf(″Iwillrunforever.\n″);實際上,for(;;)語句也不能保證一個循環無限進行,當在循環體中遇到break語句時,將立即引起循環退出。例如:如果三個表達式都省略,則for是無循環終止條件的循環,因此有38 i=l; for(;;) { s=s+i; i++; if(i>100)break ; /*如果i>100,則退出循環*/} i=l;392.for語句中的逗號表達式 逗號運算符的主要應用就是在for語句中。for語句中的表達式l和表達式3可以是逗號表達式,特別是在有兩個循環變量參與對循環控制的情況下。若表達式1和表達式3為逗號表達式,將使程序顯得非常清晰。2.for語句中的逗號表達式40 例如: #include<stdio.h> main() { inti,j; for(i=1,j=10;i<=j;i++,j--) printf(″i=%d,j=%d\n″,i,j);} 例如:41 運行結果是: i=1,j=l0 i=2,j=9 i=3,j=8 i=4,j=7 i=5,j=6 以上程序中,i和j都是循環控制變量,for語句的表達式l是逗號表達式,它為兩個循環變量賦初值:i=l,j=10;表達式3也是逗號表達式,它們的作用是修正兩個循環控制變量的值:i++,j--。 運行結果是:423.循環體為空語句 C語言的句法允許一個語句為空,這就意味著上述類型的for循環(或其它循環)的循環體也可以為空。 對for語句,循環體為空語句的一般形式為: for(表達式1;表達式2;表達式3); 例如:求s=1+2+3+…+100可以用如下循環語句完成: for(sum=0,i=1;i<=100;sum+=i,i++); 上述for語句的循環體為空語句,不作任何操作。實際上已把求累加和的運算放入表達式3中了。3.循環體為空語句43§5.4break、continue和goto語句

這一類語句的功能是改變程序的結構,使程序從其所在的位置轉向另一處。§5.4break、continue和goto語句 這一44break語句break語句的形式為 break; break語句是限定轉向語句,它使流程跳出所在的結構,把流程轉向所在結構之后。我們已經在switch語句中使用過break語句,使流程跳出switch結構。break語句在循環結構中的作用是相同的——跳出所在的循環結構,轉向執行該循環結構后面的語句。break語句break語句的形式為45例如: main() { ints=0,i=l; for(;;) { s=s+i; i++; if(i>100)break; /*如果i>100,則退出循環*/} printf(″s=%d″,s);}

例如:46 在本程序執行中,當i>100時,強行終止for循環,繼續執行for語句的下一條語句printf(″s=%d″,s);

再比如:main(){ inti; for(i=0;i<100;i++){ printf(″%d″,i); if(i==10)break; } } 在本程序執行中,當i>100時,強行終止for循環,繼續執47 這段程序將在屏幕上顯示0~10的數字。雖然循環條件是i<100,但因為有了break語句,導致程序在i=10的時候從循環中立即退出,循環也終止了。 例5.8用for循環語句編程,將輸入的多個正數累加,當輸入的數據為負數時,則程序結束。 分析:多個正數的和用變量sum存放,初始值sum=0。每次輸入的數據存入x,如果x>=0則sum+=x,否則終止。 這段程序將在屏幕上顯示0~10的數字。雖然循環條件是i<148程序: voidmain() { longsum=0; intx; for(;;) { scanf(″%d″,&x);if(x>=0)sum+=x; elsebreak; /*輸入負數,循環結束*/ } printf(″sum=%101d″,sum); }程序:49在一個switch()語句中使用break,只會影響switch,而不會影響它所在的循環。另外,一個break只能跳出最內層的循環。例如:for(i=0;i<100;i++){count=1;for(;;){printf(″%d″,count);count++;if(count==10)break;}}在一個switch()語句中使用break,只會影響swit50 這個程序將在屏幕上顯示數字1到10共100次,每當編譯程序碰到break語句,控制就回到for循環的外層。 這個程序將在屏幕上顯示數字1到10共100次,每當編譯程序51continue語句

continue語句的形式為: continue;continue語句被稱為繼續語句。該語句的功能是使本次循環提前結束,即跳過循環體中continue語句后面尚未執行的循環體語句,繼續進行下一次循環的條件判別。continue語句

continue語句的形式為:52例5.9輸出100以內能被9整除的數。#include<stdio.h>main() { intn; for(n=9;n<=100;n++) { if(n%9!=0)continue; printf(″%d″,n); }}

例5.9輸出100以內能被9整除的數。53 在本例中,對9~100的每一個數進行測試,如該數不能被9整除,即模運算不為0,則由continue語句轉去下一次循環,只有模運算為0時,才能執行后面的printf語句,輸出能被9整除的數。 在本例中,對9~100的每一個數進行測試,如該數不能被9整54例5.10顯示輸入的字符,如果按的是Esc鍵,則退出循環;如果按的是Enter鍵,則不做任何處理,繼續輸入下一個字符。 #include″conio.h″ main() { charch;for(;;) { ch=getch(); *字符輸入函數*/ if(ch==27)break; /*Esc鍵的ASCII碼為27*/

例5.10顯示輸入的字符,如果按的是Esc鍵,則退出循環55 if(ch==13)continue; /*按的是Enter鍵,跳過字符輸 出語句*/ putch(ch); /*顯示輸入的字符*/ } getch(); /*讓程序停一下,按任意鍵繼續*/ } if(ch==13)continue; 56說明: getch()和putch()的作用與getchar()和putchar()相似。不同的是: (1)getch()不顯示鍵盤輸入的字符。 (2)getchar()輸入字符時,要按Enter鍵,計算機才會響應。而用getch()時,輸入字符不需要回車。說明:57goto語句 goto語句被稱為無條件轉移語句. 它的一般形式為: goto標號; 執行goto語句使流程轉移到相應標號所在的語句,并從該語句繼續執行。語句標號用標識符表示,即以字母或下劃線開頭,由字母、數字和下劃線組成。 標號語句的形式是: 標號:語句goto語句58下面我們用goto語句來實現求平均成績的任務。 #include″stdio.h″ main() { floatscore,average=0; intn=0; scanf(″%f″,&score); /*輸入第一個學生的分數*/ if(score<0)gotoend; /*表達式為非0,轉移到end標號處*/ loop:average+=score; n++; scanf(″%f″,&score);下面我們用goto語句來實現求平均成績的任務。59if(score>=0) /*表示式為非0,轉移到loop標號處*/gotoloop;average=average/n; /*求平均成績average*/end:printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/}if(score>=0) /*表示式為非0,轉移到loop60 if(score>=0) /*表示式為非0,轉移到loop標號處*/ gotoloop; average=average/n; /*求平均成績average*/ end:printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/ } if(score>=0) 61 goto語句只能使流程在函數內轉移,不得轉移到該函數外。break語句只能終止循環層,需要從多重循環的內層一下轉移到最外層時,可以使用goto語句。 從上面使用goto語句進行循環的程序可以看出,goto語句使程序的結構性和可讀性都變差,要盡量避免使用goto語句。 goto語句只能使流程在函數內轉移,不得轉移到該函數外。b62§5.5循環的嵌套 在循環體語句中又包含有另一個完整的循環結構的形式,稱為循環的嵌套。嵌套在循環體內的循環體稱為內循環,外面的循環體稱為外循環。如果內循環體中又有嵌套的循環語句,則構成多重循環。While、do-while、for三種循環都可以互相嵌套。§5.5循環的嵌套 在循環體語句中又包含有另一個完整的循環63 例5.11輸出n×n個字符′*′。 分析: (1)n行′*′的輸出,可用下列循環控制: for(i=1;i<=n;i++) (2)每行n個′*′的輸出,可用下列循環語句實現: for(j=1;j<=n;j++) putchar(′*′); putchar(′\n′); 所以輸出n*n行“*”可用雙重循環語句實現如下:

例5.11輸出n×n個字符′*′。64 for(i=1,i<=n;i++) { for(j=1;j<=n;j++) putchar(′*′); /*輸出一行′*′*/ putchar(′\n′); /*換行*/ } 這是循環控制變量之間沒有依賴關系的多重循環。許多情況下,內循環的循環控制變量的初值或終值依賴于外循環控制變量 for(i=1,i<=n;i++)65 例5.12 編寫程序輸出如下圖形。 * ** *** **** ***** 分析: 用循環控制變量i(1≤i≤5)控制輸出行, for(i=1,i<=5,i++) 例5.12 編寫程序輸出如下圖形。66 (2)每行上的′*′個數是隨著行控制變量i的值變化而變化的。 i=1時,執行1次putchar(′*′); i=2時,執行2次putchar(′*′); …… i=5時,執行5次putchar(′*′); 輸出第i行時執行i次“putchar(′*′);”,所以內循環體語句應如下: for(j=1,j<=i;j++) (2)每行上的′*′個數是隨著行控制變量i的值變化而變化的67 putchar(′*′); /*輸出一行′*′*/輸出該圖形的完整的二重循環結構如下: for(i=1;i<=5;i++) { for(j=1;j<=i;j++) putchar(′*′); /*輸出第i行′*′*/ putchar(′\n′); } putchar(′*′); 68 以上兩個例子都是兩重for循環嵌套。另外,三種循環語句也可以互相嵌套。例如: (1)while() {… for(;;) {…} } (2)do {… while() {…} }while(); 以上兩個例子都是兩重for循環嵌套。另外,三種循環語句也可69 循環嵌套的程序中,要求內循環必須被包含在外層循環的循環體中,不允許出現內外層循環體交叉的情況。如圖5.5所.圖5.5循環交叉為非法結構 循環嵌套的程序中,要求內循環必須被包含在外層循環的循環體中70 在do-while循環體內開始while()循環,但是do-while循環結束在while()循環體內,它們互相交叉,這是非法結構。圖5.5循環交叉為非法結構 do {while(); {… }while(); } 在do-while循環體內開始while()循環,但是do71§5.6程序舉例 實際問題是復雜的,解決實際問題的程序需要多種結構復合。復合結構指的是在循環體包含選擇結構,或在選擇結構中含有循環結構,含有復合結構的程序稱為復合結構程序。復合結構程序必須做到嵌套層次清楚,嵌套層次之間不能相互交叉。§5.6程序舉例 實際問題是復雜的,解決實際問題的程序需要72 例5.13下面的程序計算100至1000之間有多少個數其各位數字之和是5。程序: #include<stdio.h> main() { inti,s,k,count=0; for(i=100;i<=1000;i++) { s=0; k=i; while(k)

例5.13下面的程序計算100至1000之間有多少個數其73 { s=s+k%10; /*首先取得該數的個位*/ k/10; /*除10以后可以將最后一位數去掉*/ } if(s!=5)continue; /*如果不等于5,則判斷下一個數*/ elsecount++; /*等于5,則計數器加1*/ } printf(″%d″,count); } {74例5.14編寫給多個學生的成績評定等級的程序。分析:用循環結構控制多個學生的分數處理,輸入的分數小于0,循環結束;對于每個學生的分數用選擇結構完成評級。程序:voldmain(){inti,score;scanf(″%d″,&score);while(score>=0) /*循環結構*/{例5.14編寫給多個學生的成績評定等級的程序。75switch(score/10) /*循環體嵌套選擇結構*/{case10:case9:printf(″%d:A\n″,score);break;case8:case7:printf(″%d:B\n″,score);break;case6:printf(″%d:C\n″,score);break;default:printf(″%d:D\n″,score);}scanf(″%d″,&score); /*輸入下一個學生的成績*/}}switch(score/10) /*循環體嵌套選擇結構*76 例5.15找出3~1000中的全部素數。 分析: (1)素數是除1和它本身之外不能被任何—個整數所整除的自然數(1除外)。如2,3,5,7是素數。1,4,6,8,10不是素數。 (2)判斷某數i是否為素數的一個簡單辦法是用2,3,4,…,i-1這些數據逐個去除i,只要被其中的一個數整除了,則i就不是素數。數學上已證明,對于自然數i只需用2,3,4,…,i1/2測試。 (3)外層循環控制。 for(i=3;i<=1000;i++) 例5.15找出3~1000中的全部素數。77 (4)用j=2,…,i1/2測試i。如果i能被這些數中的某一個整除,i就不是素數;否則i就是素數。測試過程如下: flag=0; /*設標志*/; for(j=2;j<=sqrt(i);j++) {if(i%j==0) /*被j整除,i不是素數*/ {flag=1;break; /*標志設為1,停止測試*/ } } /*內循環*/程序流程圖如圖5.6。 (4)用j=2,…,i1/2測試i。如果i能被這些數中的某78圖5.6例5.15程序流程圖圖5.6例5.15程序流程圖79 #include<math.h> main() { unsignedinti,j,count,flag; /*用flag作標志*/ count=0; /*計數器清0*/ for(i=3;i<=1000;i++) { flag=0; for(j=2;j<=sqrt(i);j++) #include<math.h>80 { if(i%j==0) /*能整除,不是素數,標志設為1*/ {flag=l;break;} }/*內循環結束*/ if(flag==0) /*若flag為0,i是素數*/ { printf(″%4d″,i);count++; if(count%8==0)printf(″\n″);/*每行輸出8個素數*/ } } /*外循環*/ ) {81

例5.16用公式,求π的近似值,直到最后一項的絕對值小于10-6為止。圖5.7例5.16程序流程圖

圖5.7例5.16程序流程圖 例5.16用公式,求π的近似值,直到最后一項的絕對值小82 圖5.7例5.16程序流程圖 分析:這是一個累加求和問題,顯然可用循環語句來實現。在這里由于循環的次數首先并不確定,所以我們可以用while循環語句。 定義變量pi存放結果。最初pi=0; 定義變量t存放當前項。最初t=1; 循環控制:while(fabs(t)>1e-6) 循環累加:pi=pi+t; t由分子和分母兩部分組成。 分子用f表示,f的初值為1,每次符號交替f=-f;分母用v表示,初值為1,每次v的值增加2。即v+=2。 程序流程圖如圖5.7所示 圖5.7例5.16程序流程圖83圖5.7例5.16程序流程圖圖5.7例5.16程序流程圖84 程序代碼: #include<math.h> voidmain() { intf=1; floatpi=0,t=1,v=1; while(fabs(t)>1e-6) { pi=pi+t; v+=2; /*準備下一個累加的數據*/ f=-f; t=f/v; }

程序代碼:85 pi*=4; printf(″\npi=%10.8f″,pi); } 例5.17電文加密問題。已知電文加密規律為:將字母變成其后面的第4個字母,其他字符保持不變。例如,a→e,A→E,W→A。編寫一個程序,輸入—行字符,要求轉換成加密電文輸出。 pi*=4;86 分析: 輸入字符ch,如果ch是字母,則進行加密處理ch+=4; 判斷加密后ch是否超出字母的范圍,如果超過,則ch-=26; 循環控制條件: ch!=′\n′。 程序流程圖如圖5.8所示。 分析:87圖5.8例5.17程序流程圖圖5.8例5.17程序流程圖88 程序: #include<stdio.h> voidmain() { charch; while((ch=getchar())!=′\n′) { if((ch>=′a′&&ch<=′z′||(ch>=′A′ &&ch<=′Z′)) { ch+=4; /*ch是字母,進行加密處理*/ if((ch>′Z′&&ch<′a′)||(ch>′z′)) /*ch在加密后越界*/

程序:89 ch-=26; }

printf(″%c″,ch);/*輸出電文*/

} } 運行時,輸入:student123↙ 輸出結果:wxyhirx123 ch-=26;90第五章循環結構程序設計§5.1概述前面已介紹了順序結構,選擇結構,本章介紹循環結構。如:

sum=1+2+3+…+100;實際問題:一組重復執行的語句。第五章循環結構程序設計§5.1概述前面已91則用循環結構解決。C語言用四種形式循環2.do-while語句3.For語句4.break、continue和goto語句1.

While語句則用循環結構解決。C語言用四種形式循環2.do-whi92§5.2while語句

while語句在C語言中用得比較多,它是通過判斷循環控制條件是否滿足來決定是否繼續循環,又稱“當型”循環。形式:while(表達式) 循環體語句2.執行過程:先判斷表達式的值。若0.則執行其后面的語句,否則while執行完畢。專門的當型循環語句––while語句§5.2while語句while語句在C語言中933.流程圖:表達式語句0=0下一語句將上述例子用while語句寫出while(i<=100){sum+=i;i++;}3.流程圖:表達式語句0=0下一語句將上述例子用whil94語句中應有使表達式=0的語句。否則會出現無限循環–––"死"循環。注:

while后面的語句一般為復合語句,即:加{}語句中應有使表達式=0的語句。注:while后面的95 我們來看下面的例子 例5.1寫一個程序,輸入一個班學生的成績,求全班的平均成績。 分析:輸入成績、計算平均成績都是一個重復性過程,因此可以用循環語句來實現。在這里,我們并不知有多少個學生,也就是說不知循環到底有多少次,但考慮到成績沒有負數,這樣就可以把循環條件定為:每當輸入的分數大于等于0時就繼續輸入成績;輸入的分數小于0時就停止輸入。 我們來看下面的例子96 解題步驟如下: (1)輸入一個分數 (2)當“分數>=0”時,做下列工作: ①累計總分; ②人數加一; ③輸入下一分數; (3)重復第(2)步,直到“分數<0”。 程序: #include<stdio.h> main() { floatscore,average=0; /*average存放平均成績,初值為0*/ 解題步驟如下:97intn=0; /*n用來存放學生數,初值為0*/scanf(″%f″,&score); /*輸入第一個學生的分數*/while(score>=0){average+=score; /*average先用來放總分*/n++; /*學生數增一*/scanf(″%f″,&score);/*輸入下一個學生的分數*/}intn=0; /*n用來存放學生數,初值為0*/98if(n!=0)average=average/n; /*求平均成績,average*/printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/}

在使用while語句的時候,我們要注意以下兩個問題:(1)循環體如果包含一個以上的語句,應該用花括號括起來,以復合語句的形式出現。如果不加花括號,則while語句的范圍只到while后面的第一個分號處。比如上例中,while語句中如無花括號,則while語句范圍只到“average+=score;”。if(n!=0)average=average/n; 99(2)在循環體中應有使循環趨向于結束的語句。比如上例中,循環結束的條件是“score>=0”,那么當我們把這個班的成績全部輸入完后,一定要輸入一個負數,才能使程序往下執行。(3)循環體語句有可能一次也不執行。比如說上例中,當第一次輸入的分數就為負數時,則循環體一次也不執行。(2)在循環體中應有使循環趨向于結束的語句。比如上例中,循環100§5.3do…while語句do-while語句的特點是: 先執行循環體中的語句,再通過判斷表達式的值來決定是否繼續循環,循環條件的測試是在循環的尾部進行的。它是一種專門的“直到型”循環語句。它的一般形式為:do循環體語句 while(表達式);§5.3do…while語句do-while語句的特點是101語句表達式0=03.流程:語句表達式0=03.流程:102對于例5.1用do-while語句編寫程序如下:#include<stdio.h>main(){floatscore,average=0;intn=0;do{ /*不進行判斷,先進入循環*/scanf(″%f″,&score); /*輸入學生的分數*/

對于例5.1用do-while語句編寫程序如下:103if(score>=0){average+=score;n++; }}while(score>=0); /*表達式為非0,則繼續*/if(n!=0)average/=n; /*求平均成績,average*/printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/}if(score>=0)104 例5.2編程序求1+3+5+7+9+…這樣的數之和。如果累加數大于750時,則程序終止并輸出結果。 main(){ inti=1,sum=0; while(sum<=750) {sum=sum+i;i=i+2; }printf("\n%d",sum); } 例5.2編程序求1+3+5+7+9+…這樣的數之和。如105 例5.3用do-while語句求1至1000之間滿足“用3除余2,用5除余3,用7除余2”的數,且一行只打印五個數。 分析:判斷一個數被另一個數除,用取模運算%。三個條件是“與”的關系。一行打印五個數,可以通過計數到5再回車換行。 程序代碼如下: #include<stdio.h> main() { inti=1,j=0; do { 例5.3用do-while語句求1至1000之間滿足“106if(i%3==2&&i%5==3&&i%7==2){printf(″%4d″,i);j=j+1;if(j%5==0)printf(″\n″);}i=i+1;}while(i<1000);}注意: 1、do-while語句的循環體語句至少要被執行一次,因為它是進入循環后再判別表達式。而while語句卻是首先判別表達式,如果表達式值為0,則一次循環也不執行。if(i%3==2&&i%5==3&&i%7==2)1072、循環控制變量必須在循環體內有所改變,才能使while和do-while語句的循環控制條件表達式的值不斷改變,直至循環結束。否則會造成死循環。例如: i=1; while(i<=100) putchar(′*′); i++; 這個循環永遠不會結束,因為“i++;”語句不屬于循環體中的語句,循環控制變量i沒有在循環體內被改變。程序應該作如下改變:2、循環控制變量必須在循環體內有所改變,才能使while和d108 i=1; while(i<=100) { putchar(′*′); i++; }這條循環語句執行的結果是輸出100個“*”。還可以將它改成do-while語句: i=1; do{ putchar(′*′); i++; }while(i<=100); i=1;109 大家可以看到,對于同一個問題,既可以用while語句處理,也可以用do-while語句處理。那么,它們到底有什么區別呢?

while語句與do…while語句的區別:

當第一次執行時,若表達式=0時,則while語句與dowhile有所不同,dowhile執行一次后面的語句,而while不執行。 大家可以看到,對于同一個問題,既可以用while語句處理,110§5.3for語句1.一般形式首先計算表達式1,接著執行表達式2,若表達式2的值0,則執行語句,接著計算表達式3,再判斷表達式2的值.依此重復下去,直到表達式2的值=0(假)。for語句是C語言中最有特色的循環語句,使用最為靈活方便。for(表達式1;表達式2;表達式3) 循環體語句§5.3for語句1.一般形式首先計算表1112.流程:計算表達式1求表達式2值語句計算表達式3=0(假)0(真)2.流程:計算表達式1求表達式2值語句計算表達式3=0(假1122.執行過程(1)先求解表達式1。(2)求解表達式2,若其值為真(值非0),則執行for語句中指定的循環體語句,然后執行下面第(3)步。若為假(值為0),則結束循環,轉到第(5)步。(3)求解表達式3。(4)轉回上面第(2)步繼續執行。(5)循環結束,執行for語句下面的一個語句。2.執行過程113用for語句寫出上述例子for用while代替的流程表達式1;while(表達式2){語句表達式3;}for(i=1;i<=100;i++)sum+=i;for語句完全可以用while代替,但for直觀、簡單、方便用for語句寫出上述例子for用while代替的流程for114for語句中的各表達式含義(1)表達式1:初值表達式,用于在循環開始前,為循環變量設置初始值。(2)表達式2:循環控制邏輯表達式,它控制循環執行的條件,決定循環次數。(3)表達式3:循環控制變量修改表達式,定義了循環一次,循環控制變量的變化情況。注意:①表達式1,表達式2,表達式3必須用分號隔開②只要條件為真,for循環就一直執行,一旦條件變為假,程序就從緊跟在for循環后面的語句重新開始執行。循環體語句:被重復執行的語句。for語句中的各表達式含義115下面通過一個例子來看for語句的執行過程。例5.4在屏幕上打印1到100的數字。當然解決這個問題我們可以用100個printf語句實現,但當要打印的數字量很大時,采用這種方式顯然是不合適的,我們可以用for循環語句來實現。程序如下:#include<stdio.h>main(){intx;for(x=1;x<=100;x++)printf(″%d″,x);}下面通過一個例子來看for語句的執行過程。116在這個程序中,x經初始化置為1,因為x小于100,調用printf語句x+1,并且測試x,看其是否仍然小于或等于100。重復進行這個過程,直到x大于100,循環結束。在這個例子中,x是循環控制變量:循環每重復一次x發生變化,并對x進行檢查。C語言第5章循環結構程序設計課件117例5.5寫程序計算s=1+2+3+…+100分析:此題可用循環語句來編寫程序,循環控制變量i從1增加到100。設s的初值為0,則循環體為: s=s+i; /*i=l,2,…,100*/程序:#include<stdio.h>main(){ints=0,i;for(i=l;i<100;i++)s=s+i; /*循環體語句*/printf(″s=%d″,s);}例5.5寫程序計算s=1+2+3+…+100118上面程序中,for語句的執行過程為:①計算表達式1“i=l;”,得到循環控制變量的初值;②求解表達式2,若表達式2的值為零(當x>100),則結束for循環;③執行循環體語句“s=s+i;”;④求解表達式3,“i++;”,然后轉向步驟②。上面程序中,for語句的執行過程為:119 對于for循環,有一點非常重要,即條件測試永遠是在循環開始時進行,如果在循環開始時條件為假,那么循環體語句就不會被執行。如: inti=10; for(k=10;k!=i;k++)printf(″%d″,k); printf(″%d″,k); 在這個循環程序段中,循環開始時,由于i=k,所以根本不會執行,正是由于條件表達式取值為假,循環體語句和循環的增量部分都不執行,因此,k一直為10,最后屏幕上輸出的數字也是10。 對于for循環,有一點非常重要,即條件測試永遠是在循環開120例5.6寫程序計算s=1-3+5-7…-99+101。 這個例子也可看成是數的累加,但與上面的例子稍有差別,就是相加的數一個為正數,一個為負數。程序代碼如下:#include<stdio.h>main(){inti,t=1,s=0;for(i=1;i<=101;i+=2){t=t*i;例5.6寫程序計算s=1-3+5-7…-99+101。121s=s+t;t=(-t)/i; /*正1,負1交叉*/}printf(″%d\n″,s);}s=s+t;122for語句與while語句的比較for語句等價于下列語句序列: 表達式1; while(表達式2) {語句; 表達式3; }相比之下,for語句顯得結構整齊、緊湊、清晰。for語句與while語句的比較123

for語句的變形1.表達式的省略 如果在for語句之前給循環變量賦了初值,則表達式1可以省略,但其后的分號不可省略。 對于例5.2,其循環語句可以寫成如下形式: i=1; /*在for語句之前給循環變量賦初值*/ for(;i<=100;i++) s=s+i;如果省略表達式3,則應在for語句的循環體內修改循環控制變量。for語句的變形124例如:for(i=1;i<=100;){s=s+i;i++; /*修改循環控制變量*/}例如:125如果表達式1和表達式3都省略,則for語句就相當于while語句。例如: i=l; /*for語句之前給循環變量賦初值*/ for(;i<=100;) { s=s+i; i++; /*修改循環控制變量*/ }如果表達式1和表達式3都省略,則for語句就相當于while126就相當于: i=1; while(i<=100) { s=s+i; i++; }就相當于:127如果三個表達式都省略,則for是無循環終止條件的循環,因此有可能形成無限循環,如下例所示: for(;;)printf(″Iwillrunforever.\n″);實際上,for(;;)語句也不能保證一個循環無限進行,當在循環體中遇到break語句時,將立即引起循環退出。例如:如果三個表達式都省略,則for是無循環終止條件的循環,因此有128 i=l; for(;;) { s=s+i; i++; if(i>100)break ; /*如果i>100,則退出循環*/} i=l;1292.for語句中的逗號表達式 逗號運算符的主要應用就是在for語句中。for語句中的表達式l和表達式3可以是逗號表達式,特別是在有兩個循環變量參與對循環控制的情況下。若表達式1和表達式3為逗號表達式,將使程序顯得非常清晰。2.for語句中的逗號表達式130 例如: #include<stdio.h> main() { inti,j; for(i=1,j=10;i<=j;i++,j--) printf(″i=%d,j=%d\n″,i,j);} 例如:131 運行結果是: i=1,j=l0 i=2,j=9 i=3,j=8 i=4,j=7 i=5,j=6 以上程序中,i和j都是循環控制變量,for語句的表達式l是逗號表達式,它為兩個循環變量賦初值:i=l,j=10;表達式3也是逗號表達式,它們的作用是修正兩個循環控制變量的值:i++,j--。 運行結果是:1323.循環體為空語句 C語言的句法允許一個語句為空,這就意味著上述類型的for循環(或其它循環)的循環體也可以為空。 對for語句,循環體為空語句的一般形式為: for(表達式1;表達式2;表達式3); 例如:求s=1+2+3+…+100可以用如下循環語句完成: for(sum=0,i=1;i<=100;sum+=i,i++); 上述for語句的循環體為空語句,不作任何操作。實際上已把求累加和的運算放入表達式3中了。3.循環體為空語句133§5.4break、continue和goto語句

這一類語句的功能是改變程序的結構,使程序從其所在的位置轉向另一處。§5.4break、continue和goto語句 這一134break語句break語句的形式為 break; break語句是限定轉向語句,它使流程跳出所在的結構,把流程轉向所在結構之后。我們已經在switch語句中使用過break語句,使流程跳出switch結構。break語句在循環結構中的作用是相同的——跳出所在的循環結構,轉向執行該循環結構后面的語句。break語句break語句的形式為135例如: main() { ints=0,i=l; for(;;) { s=s+i; i++; if(i>100)break; /*如果i>100,則退出循環*/} printf(″s=%d″,s);}

例如:136 在本程序執行中,當i>100時,強行終止for循環,繼續執行for語句的下一條語句printf(″s=%d″,s);

再比如:main(){ inti; for(i=0;i<100;i++){ printf(″%d″,i); if(i==10)break; } } 在本程序執行中,當i>100時,強行終止for循環,繼續執137 這段程序將在屏幕上顯示0~10的數字。雖然循環條件是i<100,但因為有了break語句,導致程序在i=10的時候從循環中立即退出,循環也終止了。 例5.8用for循環語句編程,將輸入的多個正數累加,當輸入的數據為負數時,則程序結束。 分析:多個正數的和用變量sum存放,初始值sum=0。每次輸入的數據存入x,如果x>=0則sum+=x,否則終止。 這段程序將在屏幕上顯示0~10的數字。雖然循環條件是i<1138程序: voidmain() { longsum=0; intx; for(;;) { scanf(″%d″,&x);if(x>=0)sum+=x; elsebreak; /*輸入負數,循環結束*/ } printf(″sum=%101d″,sum); }程序:139在一個switch()語句中使用break,只會影響switch,而不會影響它所在的循環。另外,一個break只能跳出最內層的循環。例如:for(i=0;i<100;i++){count=1;for(;;){printf(″%d″,count);count++;if(count==10)break;}}在一個switch()語句中使用break,只會影響swit140 這個程序將在屏幕上顯示數字1到10共100次,每當編譯程序碰到break語句,控制就回到for循環的外層。 這個程序將在屏幕上顯示數字1到10共100次,每當編譯程序141continue語句

continue語句的形式為: continue;continue語句被稱為繼續語句。該語句的功能是使本次循環提前結束,即跳過循環體中continue語句后面尚未執行的循環體語句,繼續進行下一次循環的條件判別。continue語句

continue語句的形式為:142例5.9輸出100以內能被9整除的數。#include<stdio.h>main() { intn; for(n=9;n<=100;n++) { if(n%9!=0)continue; printf(″%d″,n); }}

例5.9輸出100以內能被9整除的數。143 在本例中,對9~100的每一個數進行測試,如該數不能被9整除,即模運算不為0,則由continue語句轉去下一次循環,只有模運算為0時,才能執行后面的printf語句,輸出能被9整除的數。 在本例中,對9~100的每一個數進行測試,如該數不能被9整144例5.10顯示輸入的字符,如果按的是Esc鍵,則退出循環;如果按的是Enter鍵,則不做任何處理,繼續輸入下一個字符。 #include″conio.h″ main() { charch;for(;;) { ch=getch(); *字符輸入函數*/ if(ch==27)break; /*Esc鍵的ASCII碼為27*/

例5.10顯示輸入的字符,如果按的是Esc鍵,則退出循環145 if(ch==13)continue; /*按的是Enter鍵,跳過字符輸 出語句*/ putch(ch); /*顯示輸入的字符*/ } getch(); /*讓程序停一下,按任意鍵繼續*/ } if(ch==13)continue; 146說明: getch()和putch()的作用與getchar()和putchar()相似。不同的是: (1)getch()不顯示鍵盤輸入的字符。 (2)getchar()輸入字符時,要按Enter鍵,計算機才會響應。而用getch()時,輸入字符不需要回車。說明:147goto語句 goto語句被稱為無條件轉移語句. 它的一般形式為: goto標號; 執行goto語句使流程轉移到相應標號所在的語句,并從該語句繼續執行。語句標號用標識符表示,即以字母或下劃線開頭,由字母、數字和下劃線組成。 標號語句的形式是: 標號:語句goto語句148下面我們用goto語句來實現求平均成績的任務。 #include″stdio.h″ main() { floatscore,average=0; intn=0; scanf(″%f″,&score); /*輸入第一個學生的分數*/ if(score<0)gotoend; /*表達式為非0,轉移到end標號處*/ loop:average+=score; n++; scanf(″%f″,&score);下面我們用goto語句來實現求平均成績的任務。149if(score>=0) /*表示式為非0,轉移到loop標號處*/gotoloop;average=average/n; /*求平均成績average*/end:printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/}if(score>=0) /*表示式為非0,轉移到loop150 if(score>=0) /*表示式為非0,轉移到loop標號處*/ gotoloop; average=average/n; /*求平均成績average*/ end:printf(″%6.2f″,average); /*輸出平均成績average,保留兩位小數*/ } if(score>=0) 151 goto語句只能使流程在函數內轉移,不得轉移到該函數外。break語句只能終止循環層,需要從多重循環的內層一下轉移到最外層時,可以使用goto語句。 從上面使用goto語句進行循環的程序可以看出,goto語句使程序的結構性和可讀性都變差,要盡量避免使用goto語句。 goto語句只能使流程在函數內轉移,不得轉移到該函數外。b152§5.5循環的嵌套 在循環體語句中又包含有另一個完整的循環結構的形式,稱為循環的嵌套。嵌套在循環體內的循環體稱為內循環,外面的循環體稱為外循環。如果內循環體中又有嵌套的循環語句,則構成多重循環。While、do-while、for三種循環都可以互相嵌套。§5.5循環的嵌套 在循環體語句中又包含有另一個完整的循環153 例5.11輸出n×n個字符′*′。 分析: (1)n行′*′的輸出,可用下列循環控制: for(i=1;i<=n;i++) (2)每行n個′*′的輸出,可用下列循環語句實現: for(j=1;j<=n;j++) putchar(′*′); putchar(′\n′); 所以輸出n*n行“*”可用雙重循環語句實現如下:

例5.11輸出n×n個字符′*′。154 for(i=1,i<=n;i++) { for(j=1;j<=n;j++) putchar(′*′); /*輸出一行′*′*/ putchar(′\n′); /*換行*/

溫馨提示

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

評論

0/150

提交評論