收藏 分享(赏)

在C语言中.ppt

上传人:hskm5268 文档编号:8176572 上传时间:2019-06-12 格式:PPT 页数:33 大小:612.50KB
下载 相关 举报
在C语言中.ppt_第1页
第1页 / 共33页
在C语言中.ppt_第2页
第2页 / 共33页
在C语言中.ppt_第3页
第3页 / 共33页
在C语言中.ppt_第4页
第4页 / 共33页
在C语言中.ppt_第5页
第5页 / 共33页
点击查看更多>>
资源描述

1、1,迴圈 & 遞迴 (Loop & Recursion),Kevingyc 2009/02/15,2,迴圈,在C語言中,有以下幾種迴圈(Loop):,For Loop,While Loop,Do while Loop,3,For Loop,Format : for (init-expression ; cond-expression ; loop-expression ) statement ,Example : 請印出1到10,int i; for(i = 1; i 11; i+) printf(“%d “, i); ,4,For Loop的應用,int a33=0,1,2,3,4,5,6,

2、7,8; int i,j;for(i=0;i3;i+)for(j=0;j3;j+)printf(“%d “, aij);printf(“n”);,int array7=1,2,3,4,5,6,7; int i;for(i=0;i7;i+)arrayi *= arrayi;printf(“%d “, arrayi);,a. 利用兩個for loop印出矩陣( 巢狀迴圈 ) :,b. 把陣列的所有值平方並存回陣列:,5,While Loop,Format : while (expression) statement ,Example : 請印出1到10,int i=1; while( i 11)

3、printf(“%d “, i);i+; ,int i; for(i = 1; i 11; i+) printf(“%d “, i); ,=,6,While & For,兩者是可以互換的!,/ While version int i=1; while( i 11 ) printf(“%d “, i);i+; ,/ For version int i; for(i = 1; i 11; i+) printf(“%d “, i); ,我們用上一頁的例子來看看 :,7,While Loop的應用,int i= 1, keyIn, number, max = 0;printf(“請輸入你想輸入的數字有

4、幾個n“);scanf(“%d“,a.請讓使用者輸入數字,並找出最大的數字:,8,While Loop的應用,while(scanf(“%s“,&number) != EOF) . . . ,這個是在寫ACM題目的時候常用的技巧, 讓使用者可以無限次的輸入資料, 直到指定的終止條件時才停止迴圈,b.請讓使用者輸入資料,直到輸入EOF( ctrl + z )為止:,EOF: Windows : ctrl + Z Linux : ctrl + D,9,Do While Loop,Format : do statement while (expression);,Example : 請印出1到10,

5、int i=1; do printf(“%d “, i);i+; while( i 11);,do while 迴圈是while 迴圈的變形, 某些特殊需求時會需要用到,NOTE. do while 迴圈至少會執行一次,10,while & do while,如果我們把,expression =肚子還餓 statement=吃東西,while (expression) statement = 如果肚子還餓,就吃東西,直到肚子不餓,do statement while (expression) =先吃東西,如果肚子還餓就再吃東西,直到肚子不餓,我們看看實際的例子吧!,11,while & do

6、while的比較-實際例子,/ while int i=11; while( i 11) printf(“%d “, i);i+; ,/ do while int i=11; do printf(“%d “, i);i+; while( i 11);,12,迴圈的輔助指令- Break & Continue,/ break的例子 / 當 i = 3時,break int i; for(i = 1; i 11; i+) if( i=3 ) break; printf(“%d “, i); ,/ continue的例子 / 當 i = 7時,continue int i; for(i = 1; i

7、 11; i+) if( i=7 ) continue; printf(“%d “, i); ,Break : 執行到break時,就終止該迴圈 ( 只會跳出一層! ),Continue : 執行到continue時,就會跳到迴圈最下面而直接繼續進行迴圈,13,Break小問題,int i,j; for(i = 1; i = 5; i+) for(j = 1; j = 5; j+) printf(“%d “, j);if( i=j ) break;printf(“n“); ,1.當程式運作時,結果為何?,int i,j; for(i = 1; i = 10; i+) for(j = 1; j

8、= 5; j+) break;printf(“%d “, j);printf(“%d “, i); ,2.當程式運作時,結果為何?,Break、Continue、goto這些指令請盡量少用 以免破壞程式結構=因為會影響程式的可讀性,14,你不能不知道-迴圈的四大爆點,1.陣列操作不可以寫超過陣列大小,int a3=0,1,2; Int i; for(i=0 ;i=4;i+) printf(“%d “,ai); ,如果我們寫的範圍比我們宣告的陣列還要大, 除了會造成溢位之外還有可能會發生RE ( Runtime Error )的錯誤, 而且會跑出我們意想不到的東西,如圖中標示的那兩個數字,15,

9、你不能不知道-迴圈的四大爆點,int i; for(i=0 ;i=4;i+) int j=i;printf(“%d “,j); printf(“%d “,j);,j undeclared (first use this function),變數都有屬於他的有效範圍, 通常是在 之間 ( 全域變數為整個程式 ), 如果使用變數超出他的有效範圍時, 就會發生CE (Compile Error)的錯誤,就像下面紅色的錯誤訊息一樣,2.使用的變數都要在有效範圍內使用,16,Additional : 變數生命週期(Scope),對某一個變數來說,可以使用到這個變數的程式範圍就稱為這個變數的作用範圍,或稱

10、為變數的生命週期 (scope)。由於區塊是階層式的,大區塊可以內含小區塊,大區塊內的變數也可以在內含區塊內使用。,範圍:生於定義變數!死於區塊結束!,17,Additional : 變數週期範例,int g = 7; / global variable int main() int i = 1; / local variablechar i = k; / local variableint y = 2; / local variableprintf(“i = %d y = %d g = %dn“,i,y,g);/ printf 1printf(“i = %d y = %d g = %dn“,

11、i,y,g);/ printf 2return 0; ,/ printf 1 g = i = y =,/ printf 2 g = i = y =,107,7,7,2,1,undeclared!,18,你不能不知道-迴圈的四大爆點,for(i= 0; ;i+ ) / 沒有設終止條件,for(i= 0; i=5; ) / i不動,所以不會結束,一定要告訴迴圈什麼時候該結束,否則迴圈會沒辦法結束, 而造成 TLE( Time Limit Exceeded )的錯誤, 像以上兩個寫法都會造成無限迴圈,3.要設定合理的終止條件, 否則會造成無預期的無限迴圈( infinite loop ),19,你不

12、能不知道-迴圈的四大爆點,while(1) while(2) while(3). ,寫很多層迴圈的時候,一定會有很多括號, 這時候對應的問題就很重要了 盡量不要省略任何大括號,並且把他整理清楚 這樣對以後要除蟲(Debug)的時候會很有幫助,4.注意括號的對應, 尤其是當巢狀迴圈寫很大很複雜的時候,while(1)while(2)while(3).,20,迴圈小結,迴圈是一個程式裡面最基本的元件,所以一定要活用他,但是要注意以上的四個爆點,千萬不要去觸碰他,否則你的程式就會轟一聲地爆炸了!當你很明確的知道迴圈什麼時候會結束,用for迴圈可以有比較清楚的架構;但是當你不確定迴圈什麼時候會結束的時

13、候,反而用while迴圈會比較合適些。這些狀況在往後的程式設計上會很常碰到,仔細想想你要的終止條件到底是什麼,以及你需要做些什麼事情,就可輕易寫出正確的迴圈啦!,21,遞迴,什麼是遞迴(Recursion)? 就像剝洋蔥一樣, 一層一層的往裡面剝,所謂recursion,就是”function在自己裡面呼叫自己”, 這種結構就叫做recursion。,把問題拆成較小的相同問題, 把小問題解決了,大問題自然跟著解了。,Example : 請印出1到10,void print_all(int i) if(i!=0) print_all(i-1); printf(“%d “,i); ,22,遞迴的基

14、本結構,void recur(int k) if(k!=0)printf(“%d “,k);recur(k-1); ,假設我們有個程式是長這樣,當 k = 4的時候,void recur(int 4) if(4!=0)printf(“%d “,4);recur(4-1); ,void recur(int 3) if(3!=0)printf(“%d “,3);recur(3-1); ,void recur(int 2) if(2!=0)printf(“%d “,2);recur(2-1); ,void recur(int 1) . ,程式是這樣子運作的,23,遞迴的基本結構,void recur

15、(int k) if(k!=0)printf(“%d “,k);recur(k-1); ,好像有點不好懂,那換一個角度來想,如果現在有四個副程式,當 k = 4的時候,void recur(int 4) if(4!=0)printf(“%d “,4);recur1(4-1); ,void recur1(int 3) if(3!=0)printf(“%d “,3);recur2(3-1); ,void recur2(int 2) if(2!=0)printf(“%d “,2);recur3(2-1); ,void recur3(int 1) . ,recur = recur1 = recur2

16、= recur3,程式是這樣子運作的,24,遞迴的基本結構,void recur(int k) if(k!=0)printf(“%d “,k);recur(k-1); printf(“%d “,k); ,recur(4),基本上程式遞迴運作的情況會像下面這個圖所表示的狀況,if k = 4,recur(3),recur(2),recur(1),recur(0),True, Print(4),False, return,Print(1), return,Print(2), return,Print(3), return,Print(4),K =,Output :,True, Print(3),T

17、rue, Print(2),True, Print(1),4,3,2,1,1,2,3,4,4,3,2,1,0,25,遞迴的應用-費式數列 ( 遞迴式 ),F(n) = F(n-1) + F(n-2), F(1) = F(2) = 1,以n=5來舉例:,F(5) = F(4) + F(3),F(4) = F(3) + F(2),F(3) = F(2) + F(1),F(2) = 1,F(1) = 1,+,F(5) = F(4) + F(3) = F(3) + F(2) + F(2) + F(1) F(5) = F(2) + F(1) + F(2) + F(2) + F(1) F(5) = 1 +

18、 1 + 1 + 1 + 1 = 5,=,int F(int n) if(n=1 | n=2)return 1;elsereturn f(n-1) + f(n-2); ,26,遞迴的應用-費式數列 ( 圖表 ),F(n) = F(n-1)+F(n-2), F(1) = F(2) = 1,以n=5來舉例:,F(5)=,F(4)=,F(3)=,F(3)=,F(2)=,F(2)=,F(1)=,F(1)=,F(2)=,1,1,1,1,1,2,2,3,5,int F(int n) if(n=1 | n=2)return 1;elsereturn f(n-1) + f(n-2); ,27,遞迴的應用-求G

19、CD(最大公因數),int gcd( int a, int b ) / 全部擠在一行 return (a%b!=0) ? gcd(b,a%b): b; ,gcd(4005,2403),return gcd(2403,1602),return gcd(1602,801),= 801,= 801,= 801,int gcd( int a, int b ) if(a%b!=0) return gcd(b,a%b); else return b; ,28,迴圈 & 遞迴,兩者在大部分的情況下是可以互換的!,int gcd( int a, int b ) / recursion return (a%b!

20、=0) ? gcd(b,a%b): b; ,int gcd(int a,int b) / loop int x;dox=a%b;a=b;b=x;while(x!=0); return x; ,Recursion,Loop,當我們在coding的時候,有些時候用迴圈會比較好寫,有時候用遞迴比較簡單,但大部分時候兩者是可以互相轉換的,29,遞迴的進階思考-連通問題,什麼叫做連通?,顧名思義, 連通就是連在一起並成為一個通路,假設A是一個人,他能走到的點是他四周的八個方格裡,數字為1的點. 能走的點,即為”連通”點。依各題型的不同,所問的問題也不一樣,但概 念都是類似的。像油田數量,走迷宮都是屬於連

21、通問題,30,連通問題範例,ACM第352題就是個典型的連通問題 “假設有一塊地圖,我們以0和1來表示不同的區塊,問1在這個地圖中有幾塊(與四周的八格彼此連通的都算同一塊)?,1,1,1,1,1,1,1,1,1,1,1,0,1,2,3,4,5,0,1,2,3,4,5,區塊數 :,1,2,3,1.發現1,並將他標記成0,3.檢查四周是否有1,若有,將其標記為0,4.遞回檢查四周是否有1,若有,將其標記為0,2.區塊數加1,0,0,0,0,0,0,0,0,0,0,0,0,FINISH!,31,遞迴小結,何時該使用遞迴,是依照問題的解決方法來看,如果需要做同一件事情很多次,而且你不知道到底要做幾次的

22、話,用遞迴可能是比較好的選擇,當然用迴圈還是可以寫出來。當你程式語言越學越多、越學越深的時候,你會發現很多的函式都有用到遞迴的觀念,所以不要害怕使用遞迴,他是非常直覺的一種思考方法。,一定要設終止條件! 否則就會無窮遞迴到 system stack overflow!,32,練習題,基本題 :(迴圈)488 Triangle Wave100 The 3n + 1problem(遞迴)10696 F91408 Uniform Generator10922 2 the 9s進階題: 10018 Reverse and Add 10035 Primary Arithmetic572 Oil Deposits,33,參考資料,08年寒訓講義 07年寒訓講義 06年寒訓講義 On Internet,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报