【问题标题】:Recursive function-Java递归函数-Java
【发布时间】:2021-03-01 11:45:54
【问题描述】:

谁能解释这段代码中发生了什么。代码仅在传递 -1 时终止。在此之前,它一直要求用户输入。并且只有在终止后,它才会从输入值中打印 3 的倍数。我很困惑 x 的所有值在终止之前存储在哪里。


public class Recursion {
    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        multipleThree(in);


    }//end of main
    public static  void multipleThree(Scanner in) {
        
        System.out.println("Enter the list(-1 to terminate):");
        int x = in.nextInt();
        if (x == -1) {
            return;
        } else {
            multipleThree(in);
            if (x % 3 == 0)
                System.out.println(x + " is divisible by 3");

        }//end of else
      }//end of method
    }//end of class

【问题讨论】:

  • 每次调用方法时,都会为其变量和参数保留一些内存(通常称为帧)-因此每次调用都有自己的变量版本-因为int x在内部声明了一个变量该方法,它被保存在那个内存(帧)中。不仅与递归调用有关,而且与递归方法的工作有关。 [由于调用multipleThree后输出,所以只会在调用返回后执行]

标签: java algorithm recursion methods


【解决方案1】:

我很困惑 x 的所有值在终止之前存储在哪里。

它们存储在调用堆栈中。

一开始,调用栈只有main。然后main 调用multipleThree。这会将一个新帧推送到调用堆栈上。该框架将存储有关对 multipleThree 的调用已进行到何处、存在哪些局部变量等信息。

假设您输入了 3.x,它存储在当前堆栈顶部的帧中。 else 分支被执行,multipleThree 再次被调用,所以一个新的帧被推入调用堆栈。请注意,我们还没有完成对multipleThree 的第一次调用。当我们完成对multipleThree 的第二次调用时,我们可以回到它。请记住,您输入的 3 仍存储在调用堆栈中。

假设你接下来输入了 5,同样的事情会发生 - 数字 5 被存储在堆栈的顶部,然后当你再次调用 multipleThree 时会推送一个新帧(现在是第三次)。

最后,您输入 -1。此时,堆栈如下所示:

multipleThree (x = -1)
multipleThree (x = 5)
multipleThree (x = 3)
main

您可以在 IDE 的调试器中看到这一点。例如在 IntelliJ IDEA 中

因为您输入了 -1,所以对 multipleThree 的调用实际上完成了,因为它到达了 return 语句。现在堆栈的顶部被弹出,我们返回执行对multipleThreesecond 调用。堆栈现在看起来像这样:

multipleThree (x = 5)
multipleThree (x = 3)
main

在第二次调用中,记住 x 是 5 - 不能被 3 整除,所以我们什么都不做。现在我们完成了对multipleThree 的第二次调用,所以堆栈再次弹出:

multipleThree (x = 3)
main

现在我们终于回到执行对multipleThree 的第一次调用,此时x 是3。3 可以被3 整除,所以我们打印它。现在我们完成了对multipleThree 的第一次调用,所以我们也将 it 从堆栈中弹出。

【讨论】:

    猜你喜欢
    • 2015-07-13
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2020-07-15
    • 2012-09-19
    • 2015-03-01
    • 2018-08-07
    相关资源
    最近更新 更多