简体   繁体   English

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

[英]How does the return keyword really work?

A simple code snippet calculating the factorial of a number below:一个简单的代码片段计算下面的数字的阶乘:

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));


}
}

Here, I thought that when the value of the number becomes 1(due to recursion), it returns 1 every time and breaks out of the method and prints 1. But, it does return proper factorial value?在这里,我认为当数字的值变为1(由于递归)时,它每次都返回1并退出方法并打印1。但是,它确实返回了正确的阶乘值? As per this: Java - Does returning a value break a loop?按照这个: Java - 返回值是否会破坏循环? , shouldn't it have returned 1 every time? ,不应该每次都返回1吗? How these 2 code snippet differ in returning a value?这两个代码片段在返回值方面有何不同?

Thank You谢谢你

I have tried to explain the whole process;我试图解释整个过程; refer to this source .参考这个来源

Prior to this you should have basic understanding of call stacks, recursion, and stack frames.在此之前,您应该对调用堆栈、递归和堆栈帧有基本的了解。

A call stack is a data structure used by the program to store information about the active subroutines.调用堆栈是程序用来存储有关活动子例程的信息的数据结构。 The main reason for having a call stack is so that the program can keep track of where a subroutine should return control to once it finishes executing.使用调用堆栈的主要原因是程序可以跟踪子例程在完成执行后应将控制返回到何处。

A stack frame is a part of the call stack, and a new stack frame is created every time a subroutine is called.堆栈帧是调用堆栈的一部分,每次调用子程序时都会创建一个新的堆栈帧。 So, in our recursive factorial() method above, a new stack frame is created every time the method is called.因此,在我们上面的递归factorial()方法中,每次调用该方法时都会创建一个新的堆栈帧。 The stack frame is used to store all of the variables for one invocation of a routine.堆栈帧用于存储一次例程调用的所有变量。 So, remember that a call stack is basically a stack of stack frames.因此,请记住,调用堆栈基本上是堆栈帧的堆栈。


Let's divide the process into 4 parts, since the number chosen is 4.让我们将过程分为 4 部分,因为选择的数字是 4。

1st Iteration第一次迭代

static int factorial(4){ 

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

2nd Iteration第二次迭代

static int factorial(3){ 

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

3rd Iteration第三次迭代

static int factorial(2){ 

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

4th Iteration第四次迭代

static int factorial(1){ 

    if (1 == 1){
        return 1;
    }
    return 2 * factorial(number-1);
}
  1. You can see that the first stack frame is created with a number equal to 4.您可以看到第一个堆栈帧创建的数字等于 4。

  2. Then a call to factorial(3) is made – so the first call to factorial(4) does not run to completion because another call ( factorial(3) ) is made before the very first call to factorial can run to completion.然后调用factorial(3) - 所以对factorial(4)的第一次调用不会运行完成,因为在对factorial第一次调用可以运行完成之前进行了另一个调用 ( factorial(3) )。

  3. Same is the case for others.其他人也是如此。

  4. A stack frame is used to hold the state of the first call to factorial() .堆栈帧用于保存第一次调用factorial() It stores the local function variables (and their values) of the current invocation of factorial() , and it will also store the return address of the method that called it (since we are talking about the very first non-recursive invocation of factorial() , whatever routine invoked factorial() in the first place is where Factorial would return when it is completely done with everything ).它存储当前调用factorial()的局部函数变量(和它们的值),它还存储调用它的方法的返回地址(因为我们讨论的是第一个非递归调用factorial()首先调用factorial()任何例程都是 Factorial 在完成所有操作后将返回的地方)。

Because the stack frame also stores the return address, the factorial() function knows where to return to when it finishes running因为堆栈帧也存储了返回地址,所以factorial()函数在运行完成时知道返回到哪里

Process Execution流程执行

Finally, in the 4th stack frame, we run into our base case, which means the recursive calls are finished and then control is returned to the 3rd stack frame, where factorial(1) * 2 is calculated to be 2 , and then control is returned to the 2nd stack frame where factorial(2) * 3 is calculated to be 6 , and then control is returned to the 1st stack frame where factorial(3) * 4 is calculated to be 24 .最后,在第4 个堆栈帧中,我们遇到了我们的基本情况,这意味着递归调用完成,然后控制权返回到第3 个堆栈帧,其中factorial(1) * 2计算为2 ,然后控制权为返回到第二个堆栈帧,其中factorial(2) * 3计算为6 ,然后控制返回到第一个堆栈帧,其中factorial(3) * 4计算为24 Finally, our result of 24 is returned.最后,我们返回了24的结果。

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

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