3

请考虑以下代码:

#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()自己调用函数的原始堆栈帧都会被覆盖。

但是返回地址是什么?函数可以返回到自己的堆栈帧吗?

请帮我澄清这个疑问。

谢谢。

4

3 回答 3

6

,它不会被覆盖。这是一个普通的函数调用(在这种情况下是递归的)。你可能对你的counter变量感到困惑。这个变量被声明为static,这意味着它只被初始化一次,所以下面的行只被“执行”了一次:

static int counter=5;

换句话说,您可以将counter其视为仅初始化一次的全局变量(值为 5)。在每次调用中,main它都会递减,直到达到零。在那之后,所有main函数都返回,所以堆栈是unwinded(就像在正常的函数调用中一样)。

于 2012-10-23T07:46:11.090 回答
3

这在许多计算机语言中是很正常的,称为“递归”。每次调用函数都会创建一个新的堆栈帧,因此不会被覆盖。

外部 main() 的返回地址和往常一样是运行时库。内部 main() 的返回地址是外部 main()。

在您的示例中混淆水域的一件事是您将 counter 声明为静态的。这意味着它是在数据段的堆上而不是在堆栈上分配的(正如注释中的 alk 所解释的),因此 main() 的每次调用都共享相同的计数器实例。

于 2012-10-23T07:46:31.370 回答
1

Short answer: It's a simple case of recursion. So it will allocate new stack frames & not overwrite previous frame.

Long answer:
What happens to stack Frames when main() calls main():
C doesn't differentiate main from any other function. It's a simple, normal case of recursion. 'main' is special ONLY because, the default crt0.asm that came with the compiler (or whatever its name is in your compiler) calls main after its basic initialization (like stack pointer, etc) is done.
Apart from this difference, there is nothing, in which main is special.

于 2012-10-23T08:05:56.913 回答