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

コールスタックは 1 つです (スレッドを処理しない場合)。main現在の最後の呼び出しが何であれ、からになります。関数への各呼び出しは、スタック上に「スタックフレーム」を形成します。これには、関数への引数、戻り時に戻る戻りアドレス、および関数内のローカル変数が含まれます。

いくつかの回答で述べたように、コンパイラが最適化の一部として再帰を排除する場合があります。

于 2013-05-12T08:40:12.793 に答える
0

すべての警告とデバッグ情報 (つまり、gcc -Wall -gLinux の場合) を使用してコンパイルし、デバッガー ( gdbLinux の場合) を使用してステップ実行 (stepコマンド to gdb) し、バックトレース ( bt) を表示します。

(スレッドごとに) 1 つの呼び出しスタックがありますが、呼び出しスタックには複数の呼び出しフレームが含まれます。

マシンが関数を呼び出すと、新しいスタック フレームがコール スタックにインストール (プッシュ) されます。その関数が戻ると、現在の (最上位の) 呼び出しフレームが削除 (ポップ) されます。

ウィキペディアでコール スタックについて読んでください。末尾呼び出しについてもお読みください。

于 2013-05-12T07:17:32.730 に答える
0

関数への各呼び出しはスタック上のメモリ空間を保持するため、再帰呼び出しであるかどうかは関係ありません。他の関数への呼び出し間で他の状態がオーバーラップするのを避けるために、スタックには常に異なる領域があります。

于 2013-05-12T07:20:07.890 に答える