虽然条件在java中变为false,但循环创建无限循环

时间:2014-04-15 15:16:58

标签: java while-loop

public class Sample {

    /**
     * @param args
     */
    int array[]= {1,2,3};


    //it is used to display the array in format as 3,2,1,2,1,1

    public void sampleFunction(int size)
    {

        while(size >= 0)
        {
            System.out.println(array[size]);
            sampleFunction(size-1);
        }
        //end while loop

    }
    //end sample function

    // starting main class

    public static void main(String[] args) {
        //creating object Sample

        Sample s = new Sample();

    //Calling sample function for display the array elements

        s.sampleFunction(2);
    }
    //end main class


}
//end sample class

7 个答案:

答案 0 :(得分:3)

Java是pass by value only。您永远不会在size循环中更新while的值,因此size将始终大于0。

public void sampleFunction(int size) {
    while(size >= 0) {
        System.out.println(array[size]);
        sampleFunction(size-1);
        //this fixes your code...
        size--;
    }
}

更好的是,由于您正在处理递归方法,只需删除其中的while

public void sampleFunction(int size) {
    if (size <= 0) return;
    System.out.println(array[size]);
    sampleFunction(size-1);
}

使用while循环的问题是size的值永远不会改变。这是方法的执行方式:

public void sampleFunction(int size) {
    //removed unnecessary code that doesn't generate problems
    while(size >= 0) {
        sampleFunction(size-1);
    }
}

public void main(String[] args) {
    sampleFunction(0); //it will be infinite like this...
}

现在,当你致电sampleFunction(0)时,会发生这种情况:

  1. sampleFunction(0)被召唤。
  2. while循环将检查size(其值为0)是否大于或等于0.
  3. 由于它等于0,因此会调用sampleFunction(-1) 3.1。 sampleFunction(-1)被召唤 3.2。 while循环将检查size(其值为-1)是否大于或等于0 3.3。由于条件不满足,什么都不做 3.4。完成sampleFunction(-1)执行。
  4. 返回while支票。 size值永远不会改变。回到2(因此得到无限循环)。
  5. 定义递归方法时的提示:

    • 始终在方法顶部定义基本案例(如果不能在顶部,请尽快在方法中定义)。
    • 完成设计后,使用纸张和铅笔(或笔)对其进行测试,并尝试按照那里执行(不是通过在PC中执行)。这将帮助您检查是否遗漏了某些内容。一旦你获得了更多的经验,你就可以更多地相信设计并运行它(希望它不会变得无限:P)。

答案 1 :(得分:1)

如果你想要递归,为什么不简单:

public void sampleFunction(int size)
{
    if(size >= 0)
    {
        System.out.println(array[size]);
        sampleFunction(size-1);
    }
}

答案 2 :(得分:0)

public void sampleFunction(int size)
{

    while(size >= 0)
    {
    System.out.println(array[size]);
    sampleFunction(size-1);
    }
//end while loop

}

你将递归调用与命令式循环混淆,你应该选择一个:

public void sampleFunction(int size)
{

    while(size >= 0)
    {
    System.out.println(array[size]);
    size--;
    }
//end while loop

}

public void sampleFunction(int size)
{

    System.out.println(array[size]);
    sampleFunction(size-1);
    }

答案 3 :(得分:0)

您可能希望使用if而不是while,因为对于循环部分,您已经在使用递归算法。

        if(size >= 0)
        {
            System.out.println(array[size]);
            sampleFunction(size-1);
        }

这使你在每个子递归调用中接近基本条件,因为在每个递归调用大小正在递减并且在最后递归步骤中,大小将为零,这将停止递归调用自身并且你将离开你的方法最后...

答案 4 :(得分:0)

 public void sampleFunction(int size){
        while(size >= 0)
        {
            sampleFunction(size-1);
        }   
    }

慢慢思考,一步一步......

  1. 尺寸= 1

  2. 而(1&GT; = 0)

  3. 大小= 0

  4. 而(0 GT; = 0)

  5. 大小= -1

  6. 而(-1&GT; = 0)

  7. 评估错误

  8. 然后它会回到第2步,因为你在步骤2中从未完成过while循环。

  9. 解决方案是将while更改为if。你明白为什么它现在永远循环吗?在第3步中继续将大小设置为0.如果您在调试器中学习如何使用步进工具,则可以将其显示为可视化。

答案 5 :(得分:0)

你可以使用Recursion,例如:

public void sampleFunction(int size)
    {
       //Stop Condition
       if(size = 0)
        {
            System.out.println("END LOOP");
            System.out.println(array[size]);
        }
       else
        {
            System.out.println(array[size]);
            sampleFunction(size-1);
        }
    }

答案 6 :(得分:0)

要记住递归的一件事是它创建了参数和局部变量的多个副本。假设您main来电sampleFunction(4)。然后sampleFunction(4)拨打sampleFunction(3),呼叫sampleFunction(2),呼叫sampleFunction(1),呼叫sampleFunction(0)。此时,堆栈上有5个sampleFunction版本,它们同时处于活动状态; ,每个人都有自己的 size 参数。另外,如果你有一个局部变量:

public void sampleFunction(int size) {
    int x = size * 100;
    ...
}

5个版本中的每个版本也都有自己的x变量。所以现在全部活动的五种方法看起来像这样:

sampleFunction(4)   size=4  x=400   calls:
sampleFunction(3)   size=3  x=300   which calls:
sampleFunction(2)   size=2  x=200   which calls:
sampleFunction(1)   size=1  x=100   which calls:
sampleFunction(0)   size=0  x=0

您的计划中现在有五个size和五个x s。这可以帮助您了解为什么sampleFunction(0)更改sizex,只会影响其拥有 sizex };它不接触任何其他人。此外,当sampleFunction(4)调用sampleFunction(3)时,效果是创建 size变量(参数),其值为3,但这不会影响{ {1}} sampleFunction(4)完全 - 它的值为4.如果size没有做任何事情要分配给sampleFunction(4),那么它自己的size会永远是4,这就是你获得无限循环的原因。

这适用于类型为基本类型的变量,如size,也适用于类型为对象引用的变量。但请注意,它不适用于对象本身。如果你有一个递归方法,如:

int

然后如果堆栈上有五个public void recursiveMethod(MyClass c, int n) { ... recursiveMethod(c, n-1); ... } ,则会有五个不同的recursiveMethod参数,但它们都将引用同一个对象,除非其中一个c方法将自己的 recursiveMethod重新分配给其他人。