國立屏東大學 資訊工程學系 物件導向程式設計
Chicago的捷運系統自1892年起開始營運(不過它還不是世界上最早的捷運系統,London的捷運自1863年起就開始營運了),目前共有八條路線,大部份路線為高架或地面路線。Chicago的downtown稱為路普區,這是因為當捷運進入市區後,會以環狀的方式繞行一圈才離開,請見figure 1。路普的英文是Loop,意思就是繞圈。
在Java語言中,也有所謂的Loop,我們稱之為迴圈,用以重複地執行特定的程式碼。請參考figure 2,一個迴圈通常使用一組大括號將一些程式敘述包裹起來,並且反複地執行,直到特定的條件成立或不成立為止。判斷是否繼續執行的地方,可以在迴圈區塊的開頭處或是結束處,視所使用的loop敘述而定。本章將Java語言所支援的loop敘述分別加以介紹。
while敘述的語法如下:
while (controlling_expression) statements
while敘述先判斷controlling_expression的值,若為true則一直執行後續的statement,直到controlling_expression的值為false時才結束。
<note important>
</note>
所以,while迴圈中的敘述可能會被執行0次到無限多次,視其controlling_expression的值而定。以下是一些例子:
// 計算1+2+3+...+10的結果 int i=1, sum=0; //執行十次 while(i<=10) { sum+=i; i++; } System.out.printf("sum of 1 to 10 is %d.\n", sum);
// 印出介於1到100間可以被7整除的數字 int i=1; while(i<=100) { if(i%7==0) System.out.printf("%d ", i); i++; }
// 反覆執行直到使用者輸入0為止 boolean quit=false; int c; Scanner sc = new Scanner(System.in); while(!quit) { // do something ... printf("continue (0 for quit)?"); c=sc.nextInt(); if(c==0) quit=true; } sc.close();
// 反覆執行直到特定條件成立為止 while(true) { // do something ... if(expression) break; //直到特定條件成立時,使用break跳離 }
有時,不小心設定while的controlling_expression,其結果會導致程式永遠無法結束,因為不論在各種情況下,controlling_expression永遠為true。我們將這種情況稱為無窮迴圈(infinite loop),例如:
int i=0; while(i==100) //這裡將i==100寫成了i=100 { // do something ... // i++; //除錯時,不小心把這一行註解掉了 }
do敘述的語法如下:
do statements while (controlling_expression);
do迴圈與while迴圈類似,不同之處在於其判斷是否繼續之處位於exiting point。do敘述執行statements,然後才判斷接在while後面的controlling_expression的值,若為true則繼續回到do迴圈開頭處再次執行;若controlling_expression的值為false時,do迴圈才結束。相較於while迴圈,do迴圈內含的statements至少會被執行一次。以下是一些例子:
i=10; do { System.out.printf("%d\n", i); i--; } while (i>0);
i=10; do { System.out.printf("%d\n", i); } while (--i>0);
i=10; do { System.out.printf("%d\n", i); } while (i-- > 0 );
for敘述的語法如下:
for ( expression1; expression2; expression3 ) statements
其中expression1、expression2與expression3,分別是用以定義迴圈的初始條件、中止條件與更新(update)的處理,說明如下:
我們可以用while的語法,來將for的語法改寫如下:
expression1; while ( expression2) { statements expression3; }
以下是一些例子:
int i,sum=0; for(i=1;i<=10;i++) { sum+=i; } System.out.printf("sum=%d\n", sum);
在expression1與expression3中也可以用','同時指定多個運算式,例如:
int i,sum; for(i=1, sum=0;i<=10;i++) { sum+=i; } System.out.printf("sum=%d\n", sum);
expression1-3也可以被省略,例如:
int i=0; for( ; i<10;i++) System.out.printf("i=%d.\n", i);
一個迴圈內如含有另一個迴圈,則稱之為,巢狀迴圈(nested loop)。每一層的迴圈可以是for、while或do其中一個,以下我們僅以for迴圈為例,其它的組合您可以自行學習。
//印出1!+2!+3! + ... + 10! int i,j,temp,sum=0; for(i=1;i<=10;i++) { temp=1; for(j=1; j<=i; j++) { temp*=j; } sum += temp; } System.out.printf("sum=%d.\n", sum);
請思考以下問題:
除了使用迴圈的controlling_expression來控制迴圈的執行外,我們還可以使用break、continue與goto敘述來改變程式的動線,使其可以跳離迴圈所屬的程式區塊。
break在迴圈中一旦被執行,則在此次迴圈執行過程中剩下還未執行的敘述就會被跳過不執行,並且結束迴圈的執行。當迴圈的中止條件不在開頭或結尾時,break敘述就便得很有用處,例如:
//反覆要求使用者輸入一個整數,並且將其累加,直到使用者輸入0為止 int n, sum=0; Scanner sc = new Scanner(System.in); for(;;) { System.out.printf("Please input a number (0 for quit):"); n=sc.nextInt(); if(n==0) break; sum+=n; } System.out.printf("sum=%d.\n", sum); sc.close();
continue則和break相反,它並不會結束迴圈的執行,而是省略當次執行時未完成的程式碼,直接執行迴圈的下一回合。
//反覆要求使用者輸入一個整數,並且將其累加,直到使用者輸入0為止,但輸入值若為負數則加以忽略 int n, sum=0; Scanner sc = new Scanner(System.in); for(;;) { printf("Please input a number (0 for quit):"); n=sc.nextInt(); if(n==0) break; if(n<0) continue; sum+=n; // continue敘述使程式碼跳到了這裡 } System.out.printf("sum=%d.\n", sum); sc.close();