Chapter 5 迴圈 5-1 迴圈結構之 for 敘述 5-2 迴圈結構之 while 敘述 5-3 迴圈結構之 do while 敘述 5-4 continue 敘述 5-5 break 敘述 5-6 程式練習 5-7 習題
第一次學 C 就上手 若我們要使用 printf( ) 函式來印出 100 次 Hello, 假如一列一列的寫, 將會需要 100 列的 printf( Hello ); 程式敘述, 這樣的程式實在太過繁雜且撰寫耗時, 幸好 C 語言提供了迴圈結構 (Loop), 可以簡化重複動作的撰寫, 只要使用幾行迴圈程式碼, 就可顯示 100 次的 Hello 迴圈結構使得程式語言更具威力, 且善用了電腦的好處, 可以不厭其煩的重複執行特定程式敘述, 以完成指定的動作 迴圈就像是一條圓形的道路, 從原點開始走, 走一圈會回到原點, 當回到原點時, 可以選擇要不要繼續走這條圓形道路, 如果判斷條件不滿足, 則換成走其他條道路 迴圈可以重複執行一些程式敘述, 藉由執行次數的控制, 可以完成我們需要的運算, 更可以設計許多較為複雜的程式 C 語言提供了 for 迴圈 while 迴圈 do while 迴圈等迴圈結構, 接下來將分別介紹之 5-1 迴圈結構之 for 敘述 迴圈結構又稱為重複性結構, 通常在明確知道要執行迴圈的次數時, 會使用 for 迴圈來設計 for 迴圈的語法如下, 使用左大括號和右大括號將程式敘述含括起來, 如只有一行程式敘述時, 可以省略大括號 for( 起始式 ; 判斷式 ; 運算式 ) { 程式區塊 ; } 流程圖的表示法如下 : 起始式 判斷式 False 迴圈之後的敘述 True 程式區塊 運算式 5-2
迴圈 chapter 5 for 迴圈藉由 起始式 判斷式 和 運算式, 來控制迴圈的執行與結束 起始式和運算式, 都可以只是一行程式敘述 for 迴圈會依據判斷式是否滿足, 來控制程式執行的次數 起始式 : 可以初始化一個或多個變數的值 判斷式 : 運用此變數的值, 來判斷是否進入程式區塊 運算式 : 對此變數做一些運算, 例如 : 遞增或遞減運算 請參考下面的程式碼 : for(i=0;i<5;i++) printf( %d,i); 這個 for 迴圈程式會印出 01234, 而且由於 for 迴圈內只有一行程式敘述, 所以不加上大括號 程式說明如下 : 當程式第一次執行至 for 迴圈時, 變數 i 被初始化為 0, 此時變數 i 小於 5, 因此會進入程式區塊, 印出 0 之後回到迴圈的開頭, 此時不會重複起始式的敘述, 會直接做運算式的敘述, 執行 i++ 敘述將變數 i 加上 1, 然後再比對判斷式, 決定是否再次進入迴圈 for 迴圈會不斷將變數遞增後進行判斷, 直到變數 i 等於 5 之後, 判斷式 i<5 不成立, 才離開整個迴圈結構 在 for 迴圈中, 起始式 判斷式和運算式都可以為空白, 但是中 間分號仍然要寫出來, 否則會造成語法錯誤喔 5-3
第一次學 C 就上手 程式範例 : 連續印出字串程式 學習重點 : 熟悉 for 迴圈的使用方式 / 參考檔案 :5-1-1.c 使用 for 迴圈的語法, 寫出一個 C 程式, 可以連續印出 5 次 Loop is fun!, 其執行結果如下圖所示 01: /* 連續印出字串的範例 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i; 07: for(i=0;i<5;i++) 08: printf( Loop is fun!\n ); // 連續印出 5 次 Loop is fun! 09: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 10: return 0; 11: } 程式碼解說程式碼的第 1 行是程式的註解 第 2~3 行 : 含括 (#include) 進來標準輸入與輸出標頭檔 stdio.h 和標準函式庫標頭檔 stdlib.h 第 4~11 行 : 為 main( ) 函式 第 6 行 : 宣告整數變數 i 5-4
迴圈 chapter 5 第 7 8 行 : 此為 for 迴圈, 起始式 為 i=0, 判斷式 為 i<5, 運算式 為 i++ 也就是 i 從 0 開始, 每次增加 1, 只要 i 值小於 5, 就執行 for 迴圈內的程式敘述, 印出 Loop is fun! ; 所以, 該迴圈的 i 值從 0 開始, 每次加 1, 一直加到 4, 都符合判斷式 i<5 的要求,i 值的變化為 0 1 2 3 4, 當 i 等於 5 的時候便不符合判斷式的要求, 因此只會印出 5 次 Loop is fun! 第 9 行 : 使用 system( ) 函式, 讓程式暫停在執行畫面讓我們可以看到執行結果 第 10 行 : 代表 main() 函式的傳回值為整數 0 通常我們以傳回 0 代表程式正常執行完成 程式範例 :1+2+ +10 累加程式 學習重點 : 熟悉 for 迴圈的使用方式 / 參考檔案 :5-1-2.c 運用 for 迴圈, 寫出一個 C 程式, 可以計算 1+2+ +10 的結果, 其執行結果如下圖所示 01: /* 累加程式 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i,total=0; // 宣告整數變數, 並將整數變數 total 的初值設為 0 07: for(i=1;i<11;i++) 08: total = total + i; // 將 total 的值再加上 i 的值 09: printf( 1+2+ +10 = %d\n,total); // 印出 total 的值 5-5
第一次學 C 就上手 10: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 11: return 0; 12: } 程式碼解說第 6 行 : 宣告整數變數 i 和 total, 並將整數變數 total 的初值設為 0 第 7 8 行 : 為 for 迴圈, 起始式 為 i=1, 判斷式 為 i<11, 運算式 為 i++ 也就是 i 從 1 開始, 每次增加 1, 只要 i 值小於 11, 就執行 for 迴圈內的程式敘述, 執行 total = total + i; 敘述 所以,i 值的變化為 1 2 3 4 10, 當 i 等於 11 的時候便不符合判斷式的要求, 因此只會加總 1 2 3 4 10 第 9 行 : 印出加總後 total 的值, 得到 1+2+ +10 的結果 有時我們在設計程式時, 會使用 2 個以上的變數變化來完成程式設計 參考下面的程式範例, 此段程式運用整數變數 i 和整數變數 j 的遞增變化, 印出從 1 開始, 其平方小於 100 的數 int i,j; for(i=1,j=1;i*j<100;i++,j++) printf( %d * %d < 100,i,j); 5-2 迴圈結構之 while 敘述 while 迴圈的結構與 for 迴圈相似, 但是沒有起始式與運算式的區塊, 而是把起始式與運算式所需要的計算, 放到 while 迴圈的前面或迴圈內 while 迴圈的語法如下 : while( 判斷式 ) { 程式區塊 ; } 5-6
迴圈 chapter 5 流程圖的表示法如下 : 檢查判斷式是否為真 True 程式區塊 False 迴圈之後的敘述 若要將 for 迴圈的觀念用 while 迴圈表示出來, 可以將 for 迴圈的起始式放置在 while 迴圈區塊之前 ; 運算式放置在 while 迴圈區塊結束前, 最後一個程式敘述 參考下面的範例 : i = 0; while(i<5) { printf( %d,i); i++; } // 起始式 // 判斷式 // 運算式 上方的 while 迴圈範例與之前 for 迴圈的執行結果完全相同, 會印出 01234 程式範例 :1+3+5+ +99 累加程式 學習重點 : 熟悉 while 迴圈的使用 / 參考檔案 :5-2-1.c 運用 while 迴圈, 寫出一個程式, 計算級數 1+3+5+ +99 的結果 執行結果如下圖所示 5-7
第一次學 C 就上手 01: /*1+3+5+...+99 累加程式 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i=1,ans=0; 07: while(i<=99) { 08: ans = ans + i; 09: i= i+2; 10: } 11: printf("1+3+5+ +99 = %d\n",ans); 12: system("pause"); // 使程式暫停在執行畫面讓我們看到結果 13: return 0; 14: } 程式碼解說第 6 行 : 宣告整數變數 i 和 ans, 並將整數變數 i 的初值設為 1, 整數變數 ans 的初值設為 0 第 7~10 行 : 為 while 迴圈, 起始式 為 i=1, 判斷式 為 i<=99, 運算式 為 i=i+2 也就是 i 從 1 開始, 每次增加 2, 只要 i 值小於等於 99, 就執行 while 迴圈內的程式敘述, 執行 ans = ans + i; 敘述和 i= i+2; 敘述 所以,i 值的變化為 1 3 5 7 99, 當 i 等於 101 的時候便不符合判斷式的要求, 因此只會加總 1 3 5 7 99 第 11 行 : 印出加總後 ans 的值, 得到 1+3+5+ +99 的結果 5-8
第一次學 C 就上手 5-5 break 敘述 break 敘述與 continue 敘述相反, 當程式遇到 break 敘述時, 將會直接跳出迴圈, 不再執行迴圈內的敘述 參考下面的範例 : 5-5-1.c for(i=10;i<100;i++) { if(!(i%7)) break; printf( %d,i); } 上面這個範例會從 10 開始印出數字, 直到遇到 7 的倍數後, 直接跳出迴圈, 所以會印出 10 11 12 13 之值, 其執行結果如下圖所示 5-6 程式練習 程式範例 1: 印出右斜三角程式 學習重點 :for 迴圈的使用 / 參考檔案 :5-6-1.c 請運用 for 迴圈配合 printf( ) 函式, 印出如下圖排列的星形圖樣 5-12
迴圈 chapter 5 01: /* 印出右斜三角程式 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i,j; 07: for(i=1;i<6;i++) { 08: for(j=0;j<i;j++) { 09: printf( * ); // 印出星號 10: } 11: printf( \n ); // 換印下一列 12: } 13: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 14: return 0; 15: } 程式碼解說與此題類似的題目有很多, 這一類的題目其實分析上很簡單, 首先我們知道, 我們有的輸出函數必須要一行行輸出, 如果在第一層迴圈的最後, 印出換行字元 第 7~12 行 : 第一層的迴圈, 可以控制程式總共印幾行 第 8~10 行 : 第二層的迴圈, 設計每一行的輸出, 根據題目要求, 使用迴圈控制, 第一次印出一個 *, 第二次印兩個 *, 就達到題目要求了 這一類的程式, 時常成為程式設計老師考驗學生, 是否靈活應用迴圈的類型題目 5-13
第一次學 C 就上手 程式範例 2: 印出左斜三角程式 學習重點 :for 迴圈的使用 / 參考檔案 :5-6-2.c 請運用 for 迴圈配合 printf( ) 函式, 印出如下圖排列的星形圖樣 01: /* 印出左斜三角程式 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i,j,k; 07: for(i=1;i<6;i++) { 08: for(j=5-i;j>0;j--) { 09: printf( ); // 先印出每一列必須的空格 10: } 11: for(k=0;k<i;k++) { 12: printf( * ); // 印出星號 13: } 14: printf( \n ); // 換印下一列 15: } 16: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 17: return 0; 18: } 5-14
迴圈 chapter 5 程式碼解說此題與上ㄧ題範例並沒有太大差別, 需要各位讀者了解 : 第一層迴圈是用來控制換行 因此只要在輸出 星號 前, 依序輸出 4 個空格 3 個空格 就完成此題了 程式範例 3: 印出雙斜三角程式 學習重點 :for 迴圈的使用 / 參考檔案 :5-6-3.c 請運用 for 迴圈配合 printf( ) 函式, 印出如下圖排列的星形圖樣 01: /* 印出雙斜三角程式 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i; 07: for(i=0;i<5;i++) { 08: int j,k,m; 09: for(j=4-i;j>0;j--) 10: printf( ); 11: for(k=0;k<2*i+1;k++) 12: printf( * ); 13: printf( \n ); 14: } 15: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 16: return 0; 17: } 5-15
第一次學 C 就上手 程式碼解說 第 10 11 行 : 此題在印出星號的部分有一些變化, 每次會增加 2 個星號 程式範例 4: 印出 99 乘法表 學習重點 : 雙層 for 迴圈的使用 / 參考檔案 :5-6-4.c 請運用雙層 for 迴圈配合 printf( ) 函式, 印出如下圖排列的 99 乘法表 01: /*99 乘法表 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i,j; 07: for(i=1;i<10;i++) { // 外迴圈, 將被乘數每次遞增 1 08: for(j=1;j<10;j++) // 內迴圈, 將乘數每次遞增 1 09: printf("%2d*%2d=%2d",i,j,i*j); // 計算並印出 99 乘法表的值 10: printf("\n"); // 印完一列後換行 11: } 12: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 13: return 0; 14: } 5-16
迴圈 chapter 5 程式碼解說第 7~11 行 : 利用兩層迴圈來做 99 乘法表 第 7 行 : 外迴圈, 將被乘數 i 值每次遞增 1 第 8 行 : 內迴圈, 將乘數 j 值每次遞增 1 第 9 行 : 透過 i 值和 j 值的變化, 計算並印出 99 乘法表的值 程式範例 5: 計算兩數的最大公因數及最小公倍數 學習重點 :for 迴圈和取餘數的應用 / 參考檔案 :5-6-5.c 請使用者輸入兩數, 計算兩數的最大公因數與最小公倍數 下圖為使用者輸入 84 36 的執行結果 01: /* 計算兩數的最大公因數及最小公倍數 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int a,b,i,m=0,m=0; 07: printf(" 請輸入兩個正整數 :"); 08: scanf("%d %d",&a,&b); /* 輸入兩整數 */ 09: for(i=1;i<a && i<b;i++) { 10: if(!(a%i) &&!(b%i)) /* 若 a,b 可被 i 整除,i 為 a,b 之公因數 */ 11: M = i; 12: } 13: printf("%d 和 %d 之最大公因數 %d\n",a,b,m); 14: i = a<b? a:b; 5-17
第一次學 C 就上手 15: while(1) { 16: if(!(i%a) &&!(i%b)) { /* 若 i 可整除 a,b,i 為 a,b 之倍數 */ 17: m = i; 18: break; /* 第一個出現的就是最小公倍數 */ 19: } 20: i++; 21: } 22: printf("%d 和 %d 之最小公倍數 %d\n",a,b,m); 23: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 24: } 程式碼解說第 9~12 行 : 若 a,b 可被 i 整除,i 則為 a,b 之公因數, 即可求出最大公因數 第 14 行 : 利用三元運算子, 將 i 值設定為 a,b 中較小的值 第 15~21 行 : 若 i 可整除 a,b,i 則為 a,b 之倍數, 第一個出現的 i 就是最小公倍數 程式範例 6: 印出 1~100 之間的所有質數 學習重點 :for 迴圈的使用 / 參考檔案 :5-6-6.c 找出 1~100 間之質數, 然後輸出至螢幕 下圖為執行結果 01: /* 印出 1~100 之間之質數 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int i; 5-18
迴圈 chapter 5 07: for(i=2;i<101;i++) { 08: int j,flag=1; 09: for(j=2;j<i;j++) { 10: if(!(i%j)) flag = 0; 11: } 12: if(flag) 13: printf( %2d 是質數,i); 14: } 15: system( pause ); // 使程式暫停在執行畫面讓我們看到結果 16: return 0; 17: } 程式碼解說第 7~14 行 : 利用兩層 for 迴圈配合 % 取餘數運算, 來檢查是否為質數 如果有因數, 則表示不是質數,flag 值會被設為 0 如果沒有因數, 則表示是質數,flag 值會被設為 1, 並且印出質數的值 程式範例 7:1+2+4+7+11+ +106 累加程式 學習重點 :while 迴圈的使用 / 參考檔案 :5-6-7.c 寫出一個程式, 計算級數 1+2+4+7+11+ +106 的過程與結果 執行結果如下圖所示 5-19
第一次學 C 就上手 01: /* 非等距累加程式 */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: int main(void) 05: { 06: int Sum = 0,i = 1,j = 1; 07: while (i <= 106){ 08: Sum = Sum + i; 09: printf("i=%d Sum=%d\n",i, Sum); 10: i = i + j; 11: j = j + 1; 13: } 14: printf ("Sum=%d",Sum); 15: system("pause"); 16: return 0; 17: } 程式碼解說累加程式 1+2+4+7+11+ +106 與之前的範例不同點在於, 這一個級數, 每一項之間的差距, 不是等距, 其間距由 1 開始, 依次變成 2 3 4, 此處需要特別注意 程式範例 8:1+2+3+ +100 之 C++ 累加程式 學習重點 : 迴圈的使用 / 參考檔案 :5-6-8.cpp 程式會計算出 1 加到 100 的運算結果, 此範例需要使用迴圈敘述, 下圖為執行結果畫面 5-20
迴圈 chapter 5 01: #include <iostream> 02: using namespace std; 03: int main() 04: { 05: int count, sum = 0; 06: for (count = 1; count <= 100; count ++) // count<=10 迴圈成立 07: { 08: sum += count; // sum=sum+count 09: } 10: cout << "1 + 2 + 3 +... + 100 = " << sum << endl; 11: system("pause"); 12: return 0; 13: } 程式碼解說第 1 行 : 含括 (#include) 進來 iostream 標頭檔 第 2 行 : 使用 using 指令來宣告要使用 std 命名空間 第 3~13 行 : 為 main( ) 函式 第 6~9 行 : 為 for 迴圈, 從 1 累加到 100 第 10 行 : 在螢幕上印出一段文字 1 + 2 + 3 +... + 100 =, 然後接上運算結果並使用 endl 指令換行 第 11 行 : 使用 system( ) 函式, 讓程式暫停在執行畫面讓我們可以看到執行結果 第 12 行 : 程式順利結束, 回傳 0 給 main( ) 函式 5-21
第一次學 C 就上手 5-7 習題 選擇題 : ( ) 1. 在 for 迴圈中, 起始式 判斷式和運算式中間是用何種符號隔開? (a) 句號 ( ) (b) 逗號 (,) (c) 分號 (;) (d) 冒號 (:) ( ) 2. 下列何種迴圈至少會執行一次? (a) do...while 迴圈 (c) one more 迴圈 (b) while 迴圈 (d) for 迴圈 ( ) 3. 下列何種敘述會略過接下來的程式碼, 然後直接跳到下一輪的起始位置? (a) break (c) for (b) next (d) ontinue ( ) 4. 執行下列程式後,total 變數會輸出何值? for(i=0;i<=10;i++) { if(i%2) continue; total = total+i; } (a) 0 (b) 10 (c) 30 (d) 55 ( ) 5. 執行下列程式後, 會輸出何值? i=0; do { printf("%d",i); i=i+2; } while(i<5); (a) 0 (b) 024 (c) 135 (d) 012345 5-22
迴圈 chapter 5 改錯題 : 1. 在 for 迴圈中, 起始式 判斷式和運算式不可為空白 2. While 迴圈至少會執行一次 3. break 敘述會略過接下來的程式碼, 然後直接跳到下一輪的起始位置 問答題 : 1. 請說明迴圈的觀念為何? 2. 請詳細說明 for 迴圈的語法結構 程式題 : 程式題 1: 完全數尋找程式參考檔案 :5-7-1.c 題目說明 : 請撰寫一個程式, 可以進行完全數的尋找 完全數的定義為一個數等於它所有的因數和, 例如 : 6=1+2+3 28=1+2+4+7+14 請寫一個 C 語言程式, 可以找出 1~10000 之間所有的完全數, 執行結果如下圖所示 5-23