这个递归函数让我很困惑,这是怎么回事?
我正在玩递归并完成了这个简单的功能。我假设它会打印 9-0 到标准输出,但是,它打印 0-9。我根本不明白这是怎么发生的。
int main()
{
rec(10);
return 0;
}
int rec(int n){
if(n > 0)
printf("%d\n", rec(n -1));
return n;
}
I was playing around with recursion and did this simple function. I was assuming that it would print out 9-0 to stdout, but, it prints 0-9. I can't see how that happens at all.
int main()
{
rec(10);
return 0;
}
int rec(int n){
if(n > 0)
printf("%d\n", rec(n -1));
return n;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
printf
行上的rec
函数在printf
本身之前进行计算。因此,rec 函数的最深实例首先被打印。The
rec
function on theprintf
line is evaluated before theprintf
itself. Thus the deepest instance of therec
function is printed first.这样想吧。
开始放松
Think of it like this.
Start Unwinding
让我们像这样重写代码:
是否清楚为什么 0 先打印在 9 之前?
Let's rewrite your code like this:
Does it make it clear why 0 printed first before 9?
正如 Michael Burr 在评论中所说,如果您想查看发生了什么,请在启用调试符号的情况下进行编译,如下所示:
然后像这样使用 gdb 运行。
然后,要开始操作,请
在主函数中的第一次调用时输入 Which Break 。键入
以转到代码中的下一行,从那时起,只需按 Enter 键即可继续重复最后一个命令。如果您愿意,请输入
继续
以停止单步执行。您将看到每个阶段的值和评估线,这将确认上述答案。希望提供一些有用的信息。
As Michael Burr says in the comments, if you want to see what's going on, compile with debugging symbols enabled, like this:
Then run with gdb like so.
Then, to start things going, type
Which breaks at the first call in the main function. Type
to get to the next line in the code, and from then on, just press enter to keep repeating the last command. If you're happy, type
continue
to stop stepping through. You'll see the values and evaluated lines at each stage which'll confirm the above answers.Hope that provides some useful info.
因为您正在创建 9 个环境
9 > 8> 7> 6> 5> 4> 3> 2> 1> 0
,现在这些环境的处理方式与a(b(c(d(e(f(g())))))
相同,从最深的环境到第一个。请记住,当您执行此操作
printf("%d",n(m));
时,您实际上并没有打印任何内容,而是在说“打印 n(m) 的结果”,然后当它尝试解析 n(m),您正在调用另一个打印并再次说“解析 n(m-1)”。现在,当您到达 n(0) 时,它将返回 0,并由最后一次调用 printf 打印,因此它会打印 0 然后 1 .. 9。
Because you're creating 9 ambients
9 > 8 > 7 > 6 > 5 > 4> 3 > 2 > 1 > 0
, now these ambients are treated the same this woulda(b(c(d(e(f(g()))))))
, going from the deepest one to the first one.Remember that when you do this
printf("%d",n(m));
you're actually not printing anything, you're saying "print the result of n(m)" then when it tries to resolve n(m) you're calling another print and saying once again "resolve n(m-1)".Now, when you reach n(0) it will return 0 to be printed by the last call of
printf
, therefore it prints 0 then 1 .. 9.一般来说,考虑一段代码。我们说迭代和递归解决方案之间存在直接关系,因此任何解决方案都可以迭代地编写,反之亦然。然而,在某些情况下,递归地表达算法似乎更容易(例如河内塔)。在上面的代码的情况下,等效的将是 for 循环构造。
这可以作为函数实现,如下所示:
注意,这可以使用函数指针进行扩展。
In general, consider some piece of code. We say there is a direct relation between iterative and recursive solutions such that any solution can be written iteratively and vise versa. However, in some cases it is seen to be easier to express an algorithm recursively (eg. Tower of Hanoi.) In the case of the code above the equivalent would be the for loop construct.
This can be implemented as a function as follows:
Note, this can be extended using function pointers.