Java 为什么递归调用打印';123456&x27;而不是';1';?

Java 为什么递归调用打印';123456&x27;而不是';1';?,java,recursion,Java,Recursion,我很难理解代码是如何在通过x/10从原始值中取出剩余整数后恢复它们的。幕后有什么事吗 // precondition: x >= 0 // Question: What is printed from method call mystery(123456)? public void mystery(int x) { if ((x/10) != 0) { mystery(x/10); } System.out.print(x % 10); } 对神

我很难理解代码是如何在通过x/10从原始值中取出剩余整数后恢复它们的。幕后有什么事吗

// precondition: x >= 0
// Question: What is printed from method call mystery(123456)?

public void mystery(int x) {
    if ((x/10) != 0) {
        mystery(x/10);
    }
    System.out.print(x % 10);
}

对神秘()的每次递归调用都发生在打印数字的最终打印语句之前。在函数再次开始执行之前,程序的当前状态会保存到堆栈中,因此在函数的最后一次执行时,当x/10=0时,会打印1。然后程序返回到函数的上一次执行,其中x=12,并继续执行该print语句以打印12%10=2。这将以相同的方式继续,直到程序达到函数的顶级执行


解释了递归,并为阶乘示例提供了一个有用的图表,显示了如何调用和返回函数。

对神秘()的每次递归调用都发生在打印数字的最终print语句之前。在函数再次开始执行之前,程序的当前状态会保存到堆栈中,因此在函数的最后一次执行时,当x/10=0时,会打印1。然后程序返回到函数的上一次执行,其中x=12,并继续执行该print语句以打印12%10=2。这将以相同的方式继续,直到程序达到函数的顶级执行


解释了递归,并为阶乘示例提供了一个有用的图表,显示了如何调用和返回函数。

每次调用神秘函数都会在JVM中创建一个新的堆栈框架。这些帧用于存储参数、局部变量和其他数据,为了简洁起见,我将省略这些数据。在递归步骤(神秘(x/10))中,每个新创建的堆栈帧将依次保存x/10结果的较小副本。到达基本情况后,每个堆栈帧将打印其x%10的副本的值

例如,《神秘》(123456):

  • 第1帧:123456
  • 第2帧:12345
  • 第3帧:1234
  • 第4帧:123
  • 第5帧:12
  • 第6帧:1(已达到基本情况!现在将打印并返回每个帧)

模10将始终打印最右边的数字。这意味着在所有帧完成后,您将得到123456。如果您期望的是1,那么如何修改您的解决方案?(提示:考虑基本情况!)

每次神秘调用都会在JVM中创建一个新的堆栈框架。这些帧用于存储参数、局部变量和其他数据,为了简洁起见,我将省略这些数据。在递归步骤(神秘(x/10))中,每个新创建的堆栈帧将依次保存x/10结果的较小副本。到达基本情况后,每个堆栈帧将打印其x%10的副本的值

例如,《神秘》(123456):

  • 第1帧:123456
  • 第2帧:12345
  • 第3帧:1234
  • 第4帧:123
  • 第5帧:12
  • 第6帧:1(已达到基本情况!现在将打印并返回每个帧)

模10将始终打印最右边的数字。这意味着在所有帧完成后,您将得到123456。如果您期望的是1,那么如何修改您的解决方案?(提示:考虑基本情况!)

我建议在纸上解决这个问题,或者进行调试,看看“幕后”发生了什么。这里有一个提示:该方法中有一个print语句,因此每个递归调用都会打印一个内容尝试做一些研究,例如,web搜索它是否与“向堆栈添加值”有关?对函数
神秘()
的初始调用是什么?例如它是
神秘的(654321)
神秘(123456)?@RichardChambers从问题标题看,似乎最初的呼叫是神秘的(123456);我建议在纸上解决这个问题,或者进行调试,看看“幕后”发生了什么。这里有一个提示:该方法中有一个print语句,因此每个递归调用都会打印一个内容尝试做一些研究,例如,web搜索它是否与“向堆栈添加值”有关?对函数
神秘()
的初始调用是什么?例如它是
神秘的(654321)
神秘(123456)?@RichardChambers从问题标题看,似乎最初的呼叫是神秘的(123456);谢谢如果神秘参数是一个类似字符串的引用类型而不是一个基本类型,会有什么不同吗?@HelloLuna是的!我理解你的要求,但是记录字符串是不可变的。但是,如果x是可变对象的字段,那么所有堆栈帧都会看到像Obj.x=Obj.x/10这样的操作(假设它们在所有递归调用之后打印Obj.x)。在上面的例子中,我们将退出111111。谢谢!如果神秘参数是一个类似字符串的引用类型而不是一个基本类型,会有什么不同吗?@HelloLuna是的!我理解你的要求,但是记录字符串是不可变的。但是,如果x是可变对象的字段,那么所有堆栈帧都会看到像Obj.x=Obj.x/10这样的操作(假设它们在所有递归调用之后打印Obj.x)。在上面的例子中,我们将得到111111。