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()はself()を呼び出しています。

関数の元のスタックフレームは、それ自体が呼び出されるmain()たびに上書きされるようです。main()

しかし、差出人住所はどうなりますか?関数はそれ自体のスタックフレームに戻ることができますか?

この疑問を明確にするのを手伝ってください。

ありがとう。

4

3 に答える 3

6

いいえ、上書きされません。これは通常の関数呼び出しです(この場合は再帰的です)。あなたはおそらくあなたのcounter変数に混乱しています。この変数は静的として宣言されています。つまり、1回だけ初期化されるため、以下の行は1回だけ「実行」されます。

static int counter=5;

counterつまり、1回だけ初期化されたグローバル変数(値5)であるかのように考えることができます。呼び出すたびに、mainゼロに達するまでデクリメントされます。その後、すべてのmain関数が返されるので、スタックはunwinded(通常の関数呼び出しのように)なります。

于 2012-10-23T07:46:11.090 に答える
3

これは多くのコンピュータ言語ではごく普通のことであり、「再帰」と呼ばれます。関数の呼び出しごとに新しいスタックフレームが作成されるため、上書きはありません。

外側のmain()のリターンアドレスは、通常どおりランタイムライブラリです。内部main()のリターンアドレスは外部main()です。

あなたの例で水を濁らせる1つのことは、カウンターを静的として宣言したことです。つまり、スタックではなくデータセグメントのヒープに割り当てられるため(コメントのalkで説明されているように)、main()の各呼び出しは同じcounterのインスタンスを共有します。

于 2012-10-23T07:46:31.370 に答える
1

簡単な答え:これは再帰の単純なケースです。したがって、新しいスタックフレームを割り当て、前のフレームを上書きしません。

長い答え: main()がmain ()を呼び出すと
、スタックフレームはどうなりますか: Cはmainを他の関数と区別しません。これは単純で通常の再帰の場合です。'main'は、コンパイラに付属しているデフォルトのcrt0.asm(またはコンパイラでの名前が何であれ)が基本的な初期化(スタックポインタなど)が行われた後にmainを呼び出すためにのみ特別です。 この違いを除けば、メインが特別なものは何もありません。

于 2012-10-23T08:05:56.913 に答える