【问题标题】:Doesn return statement have different roles in Recursive function calling?return 语句在递归函数调用中是否有不同的作用?
【发布时间】:2014-02-16 10:58:57
【问题描述】:

我对函数中的return语句的理解是,在return之后,函数就结束了。 但这是错误的,因为我试图理解递归函数的流程:

 public class Recursions {
        int recursions(int i){
            if(i==1){
                System.out.println(i);
                return 1;
            }
            else{
                int j=(i*recursions(i-1));
                System.out.println(j);
                return j;
            }
}   
    public static void main(String[] args) {

        Recursions r=new Recursions();
        r.recursions(4);
    }
}

输出是:

1
2
6
24

但根据我的理解应该是:1 我无法理解输出,因为它表明在 return 语句后递归的情况下,指针会指向上一个调用?提前致谢

【问题讨论】:

  • return 结束 当前 函数调用,但在递归函数中,同一函数有多个调用。
  • 带有新鲜变量[i ...[i ...return] ... return]

标签: java recursion return


【解决方案1】:

区分方法(源代码中的东西)和方法调用(在运行时执行该方法)是很重要的。 return 语句结束当前方法调用。

即方法调用表达式(如recursions(i-1))被评估

  1. 留出一点内存来保存此方法调用的数据(例如方法参数和局部变量的值)。对于有技术头脑的人来说,这个内存区域称为栈帧,是当前线程栈的一部分)
  2. 评估参数表达式,并将它们的值分配给方法参数
  3. 执行方法体(直到我们到达方法体的末尾或返回语句。在后一种情况下,将返回值保留在某处)
  4. 释放为方法调用预留的内存
  5. 方法调用表达式的值是第三步计算的返回值

因此,每当执行到达方法调用表达式时,就会开始新的方法调用。一旦该方法调用终止,原始方法调用的执行将恢复。

因此,您的程序将按如下方式执行:

begin invocation of recursive with i = 4
    begin invocation of recursive with i = 3
        begin invocation of recursive with i = 2
            begin invocation of recursive with i = 1
                print 1
                return 1
            invocation ends with return value 1
            j = 2 * 1
            print j
            return j
        invocation ends with return value 2
        j = 3 * 2
        print j
        return j
    invocation ends with return value 6
    j = 4 * 6
    print j
    return j
invocation ends with return value 24

【讨论】:

    【解决方案2】:

    这种行为没有什么奇怪的,这就是递归的工作原理。如果在第一个if 之前添加println 语句:

    int recursions(int i) {
       System.out.println("------> calling recursions(" + i + ")");
       if (i == 1) {
    

    你得到这个输出:

    ------> calling recursions(4)
    ------> calling recursions(3)
    ------> calling recursions(2)
    ------> calling recursions(1)
    1
    2
    6
    24
    

    因此,当您在main() 中调用recursions(4) 时,您会得到else(因为i 是4)。所以我们得到:

    i * recursions(4-1)

    这进入recursions(3),然后得到i(现在等于3)*recursions(2)

    这反过来又让您进入recursions(2)i(现在是2)*recursions(1)

    recursion(1) 最终返回 1,并且这些值都随着先前 recursions 调用的返回值沿堆栈向上传播。在每种情况下,就在 return 语句之前,您正在打印当前 i 乘以上一次 recursions 调用的结果。

    【讨论】:

      【解决方案3】:

      每次调用函数时,都会在堆栈中创建另一个帧,

      F1,F2,F3,F4,

      例如在 F4 中调用 return 时,F4 将完成,但仍会保留其他的。 F3 将使用返回值,它也会返回另一个值。每个函数都是这样。

      【讨论】:

        【解决方案4】:

        返回后功能结束

        没有。

        返回之后,那个特定的函数调用就结束了。返回仅从对方法的 current 调用返回。它将返回给调用者,在这种情况下,调用者通常是另一个对同一方法的调用

        但根据我的理解,它应该是:1 我无法理解输出,因为它表明在 return 语句后递归的情况下指针会转到上一个调用?

        这正是发生的事情。 “先前”调用是对recursions 的外部调用。

        这就是应该发生的。不只是在 Java 中。在任何支持递归方法/函数/过程/子例程调用的编程语言中。

        【讨论】:

          猜你喜欢
          • 2020-01-04
          • 1970-01-01
          • 2019-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-08
          • 2019-01-25
          • 2018-04-05
          相关资源
          最近更新 更多