【问题标题】:Why does recursion return to first function?为什么递归返回第一个函数?
【发布时间】:2014-02-21 20:22:31
【问题描述】:

很抱歉,关于一个已经讨论过很多次的论点提出了一个非常基本的问题,我只是想不出答案。我尝试在论坛中搜索已经提出的问题,但没有找到确切的答案(或不理解)。

为什么这个函数在以不同的顺序调用时会打印两次从 i 到 10 的数字? 它不应该以相同的顺序打印出来吗?我一直听说这就是递归的工作原理:每个函数在其代码中调用另一个相同的函数,只应用于较小的域,直到满足结束条件。此时它应该返回(回溯)到原始功能;这是我不明白的,为什么它返回(不打算作为语法调用)到主函数。

void count(int i){
    if(i < 10){
          printf("%d\n", i);
          count(i + 1);
          printf("%d\n", i);
    }
}    

谢谢。

【问题讨论】:

  • 通过调试器运行您的代码并单步执行每一行,您会找到答案;)
  • 请不要将问题标记为已解决。相反,接受最有帮助的答案并保持原样。
  • @EricLippert k,我是论坛的新手,不知道规则,谢谢提醒。
  • 不用担心。有关此使用点的讨论,请参阅 meta.stackexchange.com/questions/116101/…

标签: c recursion tail-recursion


【解决方案1】:

与 7 的通话:

count(7)
    output 7
    count(8)
        output 8
        count(9)
            output 9
            count(10)
                end
            output 9
            end
        output 8
        end
    output 7
    end

为什么不应该返回?
每个函数调用有时都会返回,即使它是一个递归函数。

【讨论】:

  • 一个递归函数如果有条件终止就会返回,否则你会有一个检查当前标签的地址 ;)
  • 我明白了,所以当满足结束条件时,返回最后一个函数,然后是倒数第二个函数,以此类推,直到第一个函数。出于某种原因,我认为每个函数在调用下一个函数后立即返回,显然是错误的。现在一切都清楚了。
【解决方案2】:

与任何函数调用一样,最后,执行只是在下一行重新开始:

 printf("%d\n", i);
 // into the function
 count(i + 1);
 // out of the function
 printf("%d\n", i);

要知道的重要一点是i 的值不会更新。它们不是同一个变量。 i 有十个不同的“版本”。

 printf("%d\n", i); // i is 3
 count(i + 1);
 printf("%d\n", i); // i is still three, but a version of the function just ran where i is 4

如果您想象在看到 count(i + 1) 时只是将代码粘贴进去,那么在展开 count(8) 时会得到这个:

if(8 < 10){
      printf("%d\n", 8);
      count(8 + 1);
      printf("%d\n", 8);
}

现在粘贴:

if(8 < 10){
    printf("%d\n", 8);
    if(9 < 10){
        printf("%d\n", 9);
        count(9 + 1);
        printf("%d\n", 9);
    }
    printf("%d\n", 8);
}

再说一遍:

if(8 < 10){
    printf("%d\n", 8);
    if(9 < 10){
        printf("%d\n", 9);
        if(10 < 10){
            // we'll never get here
        }
        printf("%d\n", 9);
    }
    printf("%d\n", 8);
}

这是实际运行的代码。 i 的“旧”值不会改变。最后,您有 10 个不同的 i 变量,它们来自您调用函数的所有不同时间。

【讨论】:

  • 现在一切都清楚了,每个函数都从“最小的”返回到第一个。这是我以前不明白的。
猜你喜欢
  • 2021-12-23
  • 1970-01-01
  • 2020-11-18
  • 2022-08-13
  • 2021-11-13
相关资源
最近更新 更多