【问题标题】:How does the return keyword really work?return 关键字是如何真正起作用的?
【发布时间】:2016-08-30 17:22:11
【问题描述】:

计算下面一个数的阶乘的简单代码sn-p:

public class Main{

static int factorial(int number){       

    System.out.println("At factorial("+number+")");

    if (number == 1){
        return 1;
    }
    return number * factorial(number-1);
}

public static void main(String[] args){

    System.out.println("factorial(4) = "+ factorial(4));


}
}

在这里,我认为当数字的值变为1时(由于递归),它每次都返回1并跳出方法并打印1。但是,它确实返回了正确的阶乘值吗? 按照这个:Java - Does returning a value break a loop?,它不应该每次都返回 1 吗?这两个代码 sn-p 在返回值方面有何不同?

谢谢

【问题讨论】:

  • 返回到调用方法的时间。在纸上画出方法
  • 你应该了解调用堆栈。
  • 运行程序。如果您想查看您返回的值,请为此添加一条日志语句。 int result = number * factorial(number-1); System.out.println("At factorial("+number+") = " + result); return result; int 会很快溢出阶乘。
  • @Narasimhan 我已经解释过了,请通过

标签: java


【解决方案1】:

我试图解释整个过程;参考this source

在此之前,您应该对调用堆栈、递归和堆栈帧有基本的了解。

调用栈是程序用来存储活动子程序信息的数据结构。拥有调用堆栈的主要原因是程序可以跟踪子例程在完成执行后应将控制权返回到的位置。

栈帧是调用栈的一部分,每次调用子程序都会创建一个新的栈帧。因此,在我们上面的递归factorial() 方法中,每次调用该方法时都会创建一个新的堆栈帧。堆栈帧用于存储一次例程调用的所有变量。所以,请记住,调用堆栈基本上是堆栈帧的堆栈。


让我们把这个过程分成 4 个部分,因为选择的数字是 4。

第一次迭代

static int factorial(4){ 

    if (4 == 1){
        return 1;
    }
    return 4 * factorial(3);
}

第二次迭代

static int factorial(3){ 

    if (3 == 1){
        return 1;
    }
    return 3 * factorial(2);
}

第三次迭代

static int factorial(2){ 

    if (2 == 1){
        return 1;
    }
    return 2 * factorial(1);
}

第四次迭代

static int factorial(1){ 

    if (1 == 1){
        return 1;
    }
    return 2 * factorial(number-1);
}
  1. 您可以看到第一个堆栈帧是使用等于 4 的数字创建的。

  2. 然后调用 factorial(3) - 所以对 factorial(4) 的第一次调用不会运行完成,因为在第一次调用 factorial 之前进行了另一个调用 (factorial(3))完成。

  3. 其他人也是如此。

  4. 堆栈帧用于保存对factorial() 的第一次调用的状态。它存储当前调用factorial() 的局部函数变量(及其值),它还将存储调用它的方法的返回地址(因为我们正在讨论@987654333 的第一个非递归调用@,首先调用factorial() 的任何例程都是Factorial 在完全完成所有操作后返回的地方)。

因为栈帧也存储了返回地址,所以factorial()函数运行完就知道返回到哪里了

流程执行

最后,在第 第 4 个 堆栈帧中,我们遇到了基本情况,即 表示递归调用完成,然后将控制权返回给 第 3 个 堆栈帧,其中factorial(1) * 2 计算为 2,然后控制返回到2nd堆栈帧,factorial(2) * 3被计算为6,然后控制是 返回到factorial(3) * 4 所在的第一个堆栈帧 计算为24。最后返回我们24的结果。

【讨论】:

  • 请记住,代码刻度用于代码,并不表示强调;) 引用是引用其他媒体或使用其他文章的部分内容之类的,不应用于显示强调要么。我为你删除了所有这些东西:) 不过答案很好。
猜你喜欢
  • 1970-01-01
  • 2011-09-09
  • 2019-12-07
  • 1970-01-01
  • 2019-07-05
  • 2018-03-23
  • 1970-01-01
  • 2016-08-09
  • 2016-03-11
相关资源
最近更新 更多