繁体   English   中英

return 关键字如何真正起作用?

[英]How does the return keyword really work?

一个简单的代码片段计算下面的数字的阶乘:

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 - 返回值是否会破坏循环? ,不应该每次都返回1吗? 这两个代码片段在返回值方面有何不同?

谢谢你

我试图解释整个过程; 参考这个来源

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

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

堆栈帧是调用堆栈的一部分,每次调用子程序时都会创建一个新的堆栈帧。 因此,在我们上面的递归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()的局部函数变量(和它们的值),它还存储调用它的方法的返回地址(因为我们讨论的是第一个非递归调用factorial()首先调用factorial()任何例程都是 Factorial 在完成所有操作后将返回的地方)。

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

流程执行

最后,在第4 个堆栈帧中,我们遇到了我们的基本情况,这意味着递归调用完成,然后控制权返回到第3 个堆栈帧,其中factorial(1) * 2计算为2 ,然后控制权为返回到第二个堆栈帧,其中factorial(2) * 3计算为6 ,然后控制返回到第一个堆栈帧,其中factorial(3) * 4计算为24 最后,我们返回了24的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM