这个递归函数让我困惑,发生了什么?
我正在玩递归,并做了这个简单的功能。我假设它会打印出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;
}
正如迈克尔·伯尔在评论中说,如果你想看看发生了什么事情,编译调试符号启用,像这样:
gcc -o test -g test.c
然后像这样用gdb运行。
gdb test
然后,开始去的东西,类型
start
其中在主函数的第一个电话打破。类型
step
到达代码中的下一行,然后按回车继续重复上一条命令。如果您感到高兴,请输入continue
以停止逐步完成。你会看到每个阶段的价值观和评估线,这将确认上述答案。
希望提供一些有用的信息。
另一个有用的GDB命令是'list',它显示了源文件中的一些行。 – 2010-04-06 22:27:20
@Thomas可以自由编辑任何你认为有用的东西! – 2010-04-06 22:28:11
谢谢,那太好了。我没有太多有关gdb的经验,所以这是完美的。我会试一试。 – Fred 2010-04-06 22:35:01
想想这样。
rec(10)
rec(9)
rec(8)
rec(7)
rec(6)
rec(5)
rec(4)
rec(3)
rec(2)
rec(1)
rec(0)
开始平仓
printf("%d\n", 0);
printf("%d\n", 1);
printf("%d\n", 2);
printf("%d\n", 3);
printf("%d\n", 4);
printf("%d\n", 5);
printf("%d\n", 6);
printf("%d\n", 7);
printf("%d\n", 8);
printf("%d\n", 9);
谢谢你,这是一个很好的解释。正如所建议的那样,我也会在调试器中看看。 – Fred 2010-04-06 22:33:03
让我们重新编写这样的代码:
int rec(int n){
if(n > 0)
{
int retval = rec(n -1);
printf("%d\n", retval);
}
return n;
}
是否说清楚为什么0第一印刷前9?
如果我打算打印它,我通常会嵌套这样的函数,这是printf也是rec函数的一部分,这让我觉得困惑。谢谢 – Fred 2010-04-06 22:38:50
由于您正在创建9个环境9 > 8 > 7 > 6 > 5 > 4> 3 > 2 > 1 > 0
,现在这些环境的处理方式与a(b(c(d(e(f(g()))))))
相同,从最深的一个到第一个。
请记住,当你这样做的时候,你实际上并没有打印任何东西,而是说“打印n(m)的结果”,然后当它试图解析n(m)时,再次说“解决n(m-1)”。现在
,当到达N(0)将返回0到的printf
最后一次调用被打印,因此它打印0,则1。9.
谢谢,这非常有用!虽然之前我还没有真正给出过递归,只是决定开始做一些实验。这就说得通了。 – Fred 2010-04-06 22:47:06
int main()
{
rec(10);
return 0;
}
int rec(int n){
if(n > 0)
printf("%d\n", rec(n -1));
return n;
}
一般来说,考虑一些片的代码。我们说迭代和递归解决方案之间有直接的关系,任何解决方案都可以迭代编写,反之亦然。然而,在某些情况下,递归表达算法更容易(例如河内塔。)在上面的代码的情况下,将是for循环结构。
void _for(int i, int n)
{
if(i >= n) return; // TERMINAL<br />
// some expression (ie. printf("%d\n",i);)<br />
_for(i+1,n) // RECURSION<br />
}
注意,这可以通过使用函数指针被扩展:
这可以作为一个函数,如下所示来实现。
可能要查看降价编辑器FAQ。 http://stackoverflow.com/editing-help – ChaosPandion 2010-04-06 23:41:55
如果下面的解释不'点击',你可能会很好地在调试器中执行执行,看看发生了什么。 – 2010-04-06 22:09:13
顺便说一下,一个好的程序员应该能够阅读这个函数(在面试时可能?),他们不应该写这样的代码。好的代码不应该让你思考。 – 2010-04-06 23:07:02