请考虑以下代码:
#include <stdio.h>
int main()
{
static int counter=5;
printf ("Counter = %d\n", counter);
if (counter--)
{
main();
}
return 0;
}
编译:
gcc test.c -ansi -Wall –pedantic
执行:
[root@mars home]# ./a.out
Counter = 5
Counter = 4
Counter = 3
Counter = 2
Counter = 1
Counter = 0
这里main()调用自己()。
每次main()
被调用时,main()
函数的原始堆栈框架都会被覆盖。
但回信地址是什么?函数可以返回自己的堆栈框架吗?
请帮我澄清这个疑问。
感谢。
答案 0 :(得分:6)
否不会被覆盖。这是一个正常的函数调用(在这种情况下是递归的)。您可能会对counter
变量感到困惑。此变量声明为静态,这意味着仅初始化,因此下面的行仅“执行”一次:
static int counter=5;
换句话说,您可以将counter
视为仅仅初始化一次的全局变量(值为5)。在main
的每个调用中,它递减直到它达到零。在那之后,所有main
函数都会返回,因此堆栈为unwinded
(与正常函数调用一样)。
答案 1 :(得分:3)
在许多计算机语言中这是很正常的,称为“递归”。为每次调用函数创建一个新的堆栈帧,因此不会覆盖。
外部main()的返回地址与往常一样是运行时库。内部main()的返回地址是外部main()。
在你的例子中混淆水域的一件事是你宣称反击是静态的。这意味着它在数据段中的堆上而不是在堆栈上分配(如注释中的alk所解释的),因此每次调用main()都会共享相同的counter实例。
答案 2 :(得分:1)
简短回答:这是一个简单的递归案例。所以它将分配新的堆栈帧和不会覆盖前一帧。
答案很长:
当 main()调用 main()时,堆叠帧会发生什么情况:
C不区分主要功能和其他任何功能。这是一个简单的,正常的递归情况。
'main'是特殊的,因为编译器附带的默认crt0.asm(或编译器中的任何名称)在完成基本初始化(如堆栈指针等)后调用main。
除了这种差异,没有什么,主要是特殊的。