死循環(endless loop)


死循環

  • 死循環就是一個無法結束的循環。(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,確實是一個負數。
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM