当我们递归调用函数时,它是否涉及单个调用堆栈或每次调用函数一个?

时间:2013-05-12 07:13:27

标签: c recursion callstack

在以下代码中,我从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);
}

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

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

在维基百科上阅读call stacks。另请阅读tail calls

答案 2 :(得分:0)

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