• 死循环(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,确实是一个负数。
        }
    }

  • 相关阅读:
    cnpm 安装和 command not found
    C#-弄懂泛型和协变、逆变
    2019年阅读
    ES5和ES6数组方法
    ASP.NET MVC中的捆绑和压缩技术
    markdown解析与着色
    Oauth2.0
    同源策略和跨域的解决方案
    windows常用命令
    Java 9 在win10环境搭建
  • 原文地址:https://www.cnblogs.com/buildnewhomeland/p/12158384.html
Copyright © 2020-2023  润新知