第六章 重複結構 本投影片僅供本書上課教師使用,非經同意請勿拷貝或轉載
6-1 重複敘述 P6-2 將程式中具有某個功能的連續敘述稱為 敘述區段。 「敘述區段」需要重覆執行很多次時,可用「重覆結構」來完成。 將這些屬於重覆執行的敘述區段,稱為迴圈(Loop)。 C 語言的重覆敘述有兩種: 1. 已知重覆次數計數迴圈(for…) 2. 無法預知重覆次數條件迴圈(while 敘述及do…while敘述)。
P6-2 6-2 計數迴圈( for…)
說明 start_expression 用來設定迴圈控制變數的初值。 若start_expression 和 count_expression 若有兩個以上運算式,中間使用逗號分開。 若三個 expression 都省略,分號必須保留 如:for( ; ; ) 變成無窮迴圈。 若test_expression 結果為真(不為零),將迴圈執行 一次再執行 count_expression 一次,代入test_expression若結果為真, 再執行迴圈一次, 一直到結果為假時才離開迴圈。
P6-3
5. 若 count_expression 增值為正, 則終值必須大於或等於初值; 若增值為負,終值必須小於或等於初值。 6.從 for 迴圈中途跳出,可用 break離開 迴圈。 若要在 for 迴圈內執行到某個敘述又跳 回到 for 的開頭繼續執行可使用continue
P6-4 如 for 迴圈初值設為1;終值為10;增值1 語法如下:
8. 以下簡例為for 敘述的寫法: P6-4
P6-4
P6-5
/* FileName: series.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 03 04 int main(int argc, char *argv[]) 05 { 06 int x, sum=0 ; 07 printf("\n === 求級數的總和 ==== \n\n"); 08 printf(" x 2x+1 \n"); 09 printf(" ======= ======= \n"); 10 for (x=1; x<=5; x++) 11 { 12 printf(" %d %d \n",x,2*x+1); 13 sum+=2*x+1; 14 } 15 printf(" ---------------------------- \n"); 16 printf(" 此級數總和為 : %d \n\n",sum); 17 system("PAUSE"); 18 return 0; 19 }
6-3 break與 continue 主要用在 while 和 for敘述中,用來改變 程式執行的流程。 P6-6 6-3 break與 continue 主要用在 while 和 for敘述中,用來改變 程式執行的流程。 敘述區段中若碰到 break 敘述,馬上 中 斷執行,跳到緊接在該敘述區段後面 的敘 述繼續執行。 continue 敘述跳到該敘述區段的最前面 執行。
P6-6
說明 continue 與 break 敘述的差別 P6-7 說明 continue 與 break 敘述的差別
P6-7
/* FileName: summax.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 03 04 int main(int argc, char *argv[]) 05 { 06 int ni, max, total=0 ; 07 printf("\n 請輸入 1+2+..+n <=max 的 max 值 : ") ; 08 scanf("%d",&max) ; 09 for (n=1 ; ; n++ ) // for 終值無法確定 10 { 11 total += n ; 12 if (total > max) 13 { 14 total -= n ; 15 n-- ; 16 break ; 17 } 18 } 19 printf("\n 1 + 2 + .... + %d <= %d \n\n", n, max) ; 20 21 system("PAUSE") ; 22 return 0 ; 23 }
P6-10
6-4 條件迴圈 當一個敘述區段重覆執行的次數無法 預測時,可使用條件式迴圈來解決。 條件式迴圈的基本形式有下列兩種: P6-11 6-4 條件迴圈 當一個敘述區段重覆執行的次數無法 預測時,可使用條件式迴圈來解決。 條件式迴圈的基本形式有下列兩種: 1. 前測式迴圈:while … 2. 後測式迴圈:do ... while
一、while (前測式迴圈) P6-9 所謂「前測式迴圈」表示會先判斷是否 滿足condition條件? 若滿足條件(為true值不為0),執行Loop Body敘述區段一次,再檢查是否滿足condition條件,一直到不滿足條件(為false 值為0)時才離開迴圈。其語法如下:
P6-10
/* FileName : arithmetic.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 03 04 int main(int argc, char *argv[]) 05 { 06 char ch1, ch2; 07 08 printf("\n ======= 四 則 運 算 ======== \n"); 09 printf("\n 1. 加 法 運 算 "); 10 printf("\n 2. 減 法 運 算"); 11 printf("\n 3. 乘 法 運 算"); 12 printf("\n 4. 除 法 運 算"); 13 printf("\n 0. 離 開 運 算"); 14 printf("\n ==============================");
15 while (1) 16 { 17 printf("\n\n 36,12 兩數做何項運算 (0-4) : "); 18 ch1=getche(); 19 switch (ch1) 20 { 21 case '0': 22 printf("\n\n 離開本程式 ... "); 23 return 0; 24 case '1': 25 printf("\n 36 + 12 = %d ",36+12); 26 break; 27 case '2': 28 printf("\n 36 - 12 = %d ",36-12); 29 break; 30 case '3': 31 printf("\n 36 x 12 = %d ",36*12); 32 break; 33 case '4': 34 printf("\n 36 / 12 = %d ",36/12); 35 break; 36 default: 37 printf("\n 錯誤選項(0-4) ! "); 38 } 39 } 40 system("PAUSE"); 41 return 0; 42 }
P6-13
/* FileName : gcdlcm.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 03 04 int main(int argc, char *argv[]) 05 { 06 int num1, num2, GCD, LCM; 07 int inLarge,inSmall,inRem; 08 printf("\n === 求兩數的最大公約數和最小公倍數 === \n"); 09 printf("\n 請輸入兩個整數 格式如 : 24,36 <Enter> : "); 10 scanf("%d, %d",&num1, &num2);
11 if (num1>num2) 12 { 13 inLarge=num1; 14 inSmall=num2; 15 } 16 else 17 { 18 inLarge=num2; 19 inSmall=num1; 20 } 21 inRem=inLarge%inSmall; 22 while(inRem!=0) 23 { 24 inLarge=inSmall; 25 inSmall=inRem; 26 inRem=inLarge%inSmall; 27 } 28 GCD=inSmall; 29 LCM=num1 * num2 / GCD; 30 printf("\n\n 計算結果 : "); 31 printf("\n\n 1. ( %d & %d )的最大公約數(G.C.D) : %d", num1, num2, GCD); 32 printf("\n\n 2. ( %d & %d )的最小公倍數(L.C.M) : %d\n\n", num1, num2, LCM); 34 system("PAUSE"); 35 return 0; 36 }
二、do … while (後測式迴圈) P6-15 「後測式迴圈」會先執行 Loop Body 一次, 再判斷是否滿足 condition,若滿足(其值不為0)會再執行Loop Body,一直到不滿足才離開迴圈。語法:
P6-16
P6-17
6-5 巢狀迴圈(Nested Loop) 是指一個程式中,若迴圈內還有迴圈, 稱為「巢狀迴圈」。 一般在製作一個二維表格如:九九乘法 表或是有規則性的表格等都可使用 「巢狀迴圈」。
01 #include <stdio.h> 02 #include <stdlib.h> 04 int main(int argc, char *argv[]) 05 { 06 int i, k; 07 int num1, sum=1; 09 printf("請輸入做多少個階乘(1-9)? "); 10 scanf( "%d",&num1); 12 printf("\n 1! %d = \n" ,1 ); 13 for (i=2 ; i<=num1; i++) 14 { 15 printf(" %d! = " ,i ); 16 sum=1; 17 for (k=1; k<i; k++) 18 { 19 printf("%d x ",k); 20 sum = sum*k ; 21 } 22 sum=sum*k; 23 printf("%d = %d \n", i, sum); 24 } 25 26 printf("\n\n"); 27 system("PAUSE"); 28 return 0; 29 }
P6-20
/* FileName : table2.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 03 04 int main(int argc, char *argv[]) 05 { 06 int row, column; 07 for (row=1; row<=5; row++) 08 { 09 for (column=1; column<=5-row;column++) 10 printf(" "); 11 for (column=1; column<=2*row-1;column++) 12 printf("*"); 13 printf("\n"); 14 } 15 printf("\n"); 16 system("PAUSE"); 17 return 0; 18 }
P6-21
/* FileName : nine.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 04 int main(int argc, char *argv[]) 05 { 06 int i, j; 07 i = 1; 08 j = 1; 09 while(i<=9) 10 { 11 while(j<=9) 12 { 13 printf(" %d*%d=%2d", i, j, i*j); /* 第一個%d前面空ㄧ格當間距 */ 14 j++; 15 } 16 printf("\n"); 17 i++; 18 j=1; 19 } 20 printf("\n\n"); 21 system("PAUSE"); 22 return 0; 23 }
6-6 實例 P6-22 【說明】 1. 朗伯特(Johann Heinrich Lambert)在西元1761年首先證明π是 無理數(不能以分數表示)。他先證明「如果x是有理數,則tan(x) 必為無理數」,因此「如果tan(x)是有理數,則x是無理數」。 因為tan(π/4)=1,所以π/4是無理數,π也必是無理數。 2. π是一個不循環的無限小數。 3. 印度的數學家尼拉堪塔在數學上,主要提出圓周長除以直徑會是 一個無理數,以及算出圓週率到小數點後十位的近似值。 4. 因為tan(π/4)=1, 且tan-1x = x - x3/3 + x5/5 - x7/7 + ...。 當x=1時, π/4 = tan-11, 所以 π/4 = 1-1/3+1/5-1/7+…+(-1)n+1/(2n-1) 即 : π = 4-4/3+4/5-4/7+…+4*(-1)n+1/(2n-1) 5. 當n的值愈大, 愈逼近圓週率。
/* FileName : pi.c */ 01 #include <stdio.h> 02 #include <stdlib.h> 03 #include <math.h> 04 int main(int argc, char *argv[]) 05 { 06 int i,j; 07 int x; 08 double PI; 10 for (j=50000;j<=1000000;j+=50000) 11 { 12 x=0; 13 PI=0; 14 for (i=1; i<=j; i++) 15 { 16 x=(int) pow(-1,i+1); 17 PI+=4* (float) x /(float) (2*i-1); 18 } 19 printf("j= %7d ==> PI = %10.8f\n", j, PI); 20 } 21 printf("\n\n"); 22 system("PAUSE"); 23 return 0; 24 }
本章結束 Take a Break …..