1

当我在下面的代码中调用函数fact()main(),此调用是否会fact()涉及单个调用堆栈,fact()或者由于fact()本质上是递归的,因此对于fact()随后的每个递归调用,它将涉及一个单独的调用堆栈?我是递归的新手,对此一无所知。

#include<stdio.h>

int fact(int);

int main(void)
{
 int a=8;
 printf("The factorial of 8 is %d",fact(a));
}

int fact(int a)
{ 
    if(a==1)
    return 1;
    return a*fact(a-1);
}
4

3 回答 3

1

有一个调用栈(除非我们处理线程)。它从main当前最后一次通话开始。对任何函数的每次调用都会在堆栈上形成一个“堆栈帧”,其中包含函数的参数、返回时返回的返回地址以及函数内的任何局部变量。

正如一些答案中提到的,在某些情况下,编译器将消除递归作为其优化的一部分。

于 2013-05-12T08:40:12.793 回答
0

编译所有警告和调试信息(即gcc -Wall -g在 Linux 上),然后使用调试器(gdb在 Linux 上)执行步骤(step命令到gdb)并显示回溯(bt)。

有一个调用堆栈(每个线程),但一个调用堆栈包含多个调用帧。

当机器调用一个函数时,一个新的栈帧被安装(推送)到调用栈上。当该函数返回时,当前(最顶层)调用框架被移除(弹出)。

在 Wikipedia 上阅读有关调用堆栈的信息。另请阅读尾调用

于 2013-05-12T07:17:32.730 回答
0

对函数的每次调用都会保留堆栈上的内存空间,因此无论是否是递归调用,堆栈上总是有不同的空间,以避免在调用其他函数之间重叠其他状态。

于 2013-05-12T07:20:07.890 回答