递归保留值中的局部变量?

时间:2018-11-10 06:48:17

标签: java recursion objectinstantiation

目前正在从事递归实践/实现,并且发现有些事情与我在编程中所知的一切都是相反的。

递归方法

protected int getArea() {

    if(width <= 0)
        return 0;
    else if(width == 1)
        return 1;
    else {

        Triangle t2 = new Triangle(width - 1);
        int area = t2.getArea();//Area variable somehow is holding the values of previous calls, despite being instantiated in each new call?

        return area + width;

    }

}

不知何故,局部变量area在递归方法中聚合来自先前调用的值。每次调用都被实例化时,这怎么可能?在每次调用中,似乎都再次调用了方法getArea(),由于area调用发生在方法之前 ,从而阻止了getArea()变量持有任何东西。 return语句。

这是怎么回事?

3 个答案:

答案 0 :(得分:3)

每个方法调用的详细信息都存储在堆栈中,一旦从方法调用返回值,执行就会返回到调用当前方法的前一个方法,局部变量值等。将被存储在堆栈中,这就是程序需要时在执行中使用这些值的方式。对递归程序进行一些实验,以了解更多有关递归程序的信息。

我的建议是尝试使用IDE上的断点(如eclipse或Intellij)调试递归程序,这将消除很多混乱并清晰地说明递归的工作方式。

答案 1 :(得分:1)

当涉及到递归时,我经常会发现记住所付出的就是所得到的会很有帮助,这意味着调用递归方法时所得到的就是 you < / em>决定从中退回。

在这种情况下,您写作时会得到什么

int area = t2.getArea();

01area + width

最后一种情况是递归情况,其中您递归定义一个新的Triangle实例,其新宽度减1,然后在其上调用.getArea()。在功能上等同于将.getArea()定义为

protected int getArea(int width) {

    if(width <= 0)
        return 0;
    else if(width == 1)
        return 1;
    else {
        int area = getArea(width - 1);
        return area + width;
    }

}

.getArea()的一个实例或另一个实例调用Triangle都没有区别。重要的是在调用width时将其定义为width - 1,以及 you 如何定义其对收益的影响值。

答案 2 :(得分:0)

我认为您看错了。如果调用两种方法。例如。

public int test() {
    int x = getSomeInt(1);
    int y = getSomeInt(2);
    return x + y;
}

您是否在质疑是否已完成return x + y或在x之前确定y的值?它从上到下执行,并且语句设置y在返回getSomeInt(1)并将其值设置为x之前不开始。 因此,以您的示例为例:

protected int getArea() {
    if (width <= 0) {
        return 0;
    } elseif (width == 1) {
        return 1;
    } else {
        Triangle t2 = new Triangle(width - 1);
        int area = t2.getArea();
        return area + width;
    }
}

因此,如果您有一个宽度为1的三角形并打电话给getArea,则会得到1的回报。

如果在宽度为2的三角形上执行此操作会怎样?好吧,它创建宽度为t2的{​​{1}}并在其上调用1。我们已经知道结果了,因为我们已经对其进行了计算。 getArea变为area,然后返回1

如果宽度为3,会发生什么?它将创建宽度为1 + 2的{​​{1}}并在其上调用t2。我们知道从上面返回2,结果为getArea()

以较高的3调用回溯方法,但是首先确定具有3 + 3的那个,然后是2,3,4,...,最后是您实际调用的调用有一些with,它添加了1

每次对拟甲醇方法的调用与被叫方无关。是的,是相同的代码,但是它是一个不同的对象,并且局部变量对于该调用是唯一的,就像两个调用area所调用的第一个参数也具有两个不同的版本一样。除非您通过引用进行更改或传递,否则它们不会纠缠在一起。

在对象上调用方法与对象在调用中作为参数非常相似。递归调用的对象具有较小的with,并且在某一时刻它将命中基本情况。您可以说是一样的:

getSomeInt

同样,..具有恢复作用的方法不会更改任何内容。没什么特别的待遇。它需要先完成调用,然后才能返回值,就像您使用其他方法来获取width中的区域一样。根本没有区别。