死迴圈 死迴圈就是一個無法結束的迴圈。(endless loop / infinite loop) 出現死迴圈是因為沒有設置好結束條件,迴圈的結束條件很重要,要充分考慮各種邊界情況。 以上一篇隨筆中的習題(找到 n 個可以被整除的數)為例,如果缺少累計次數的條件,那麼就會讓條件表達式永遠滿足,這樣程 ...
死迴圈
- 死迴圈就是一個無法結束的迴圈。(endless loop / infinite loop)
- 出現死迴圈是因為沒有設置好結束條件,迴圈的結束條件很重要,要充分考慮各種邊界情況。
以上一篇隨筆中的習題(找到 n 個可以被整除的數)為例,如果缺少累計次數的條件,那麼就會讓條件表達式永遠滿足,這樣程式就會永遠執行。這樣就會產生一個死迴圈。
public class FindDivEndless { public static void main(String[] args) { int n = 5; int dividend = 100; int divisor = 89; int found = 0; while(found<n) { if(dividend%divisor == 0) { System.out.println(dividend + "可以被" + divisor + "整除。商為" + (dividend/divisor)); } dividend++; } } }
一個特殊的例子
- 用 while 找出 5 個能被 20 0000 0000 整除的數
- 程式最終依然會結束
public class FindNDivNotEndless { public static void main(String[] args) { int n = 5; int dividend = 100; int divisor = 2000000000; // 數值會溢出int的取值範圍 int found = 0; while (found < n) { if (dividend % divisor == 0) { found++; System.out.println(dividend + "可以被" + divisor + "整除。商為" + (dividend / divisor)); } dividend++; } } }
出現這種情況的原因是,20億接近 int 的最大取值,再往下累加就會導致數值溢出。
按照二進位的加法,那麼加著加著,最高位就會是1,而在電腦中,二進位數值是用補碼的形式表示和存儲的,
因此最高位符號位是1時,就變成了負數,這就是為什麼第二個找到的數是負數的原因。
於是,如果不僅僅找5個可以被整除的數時,就會不斷的1、 -1、 0、 1、 -1 這樣重覆下去。
那麼又如何解決數值溢出而產生負數結果的問題呢?
使用 break 語句結束迴圈
- break語句可以結束任何迴圈
- 不考慮負數的情況,使用 break 解決問題
public class FindNDivBetter { public static void main(String[] args) { int n = 5; int dividend = 100; int divisor = 2000000000; int found = 0; String start = "從" + dividend + "開始,"; while (found < n) { // 當被除數數值溢出時,跳出整個while迴圈。 if (dividend < 0) { System.out.println("被除數溢出,計算結束!"); break; } if (dividend % divisor == 0) { found++; System.out.println(dividend + "可以被" + divisor + "整除。商為" + (dividend / divisor)); } dividend++; } System.out.println(start + "共找到" + found + "個可以被" + divisor + "整除的數。"); System.out.println(dividend); // 結果是-2147483648,確實是一個負數。 } }