DOUG LLOYD:あなたが見てきた場合 再帰のビデオ、 全体のプロセスは場合があります 少し魔法のようでした。 それがどのように動作しますか? 関数はどのようにということを知っていますか 別の値を待って待機する必要があり 別の関数から戻ります 私たちが望む結果を得るために呼び出しますか? さて、この作品理由があるためです コー​​ルスタックとして知られている何かの。 あなたは、関数を呼び出すと、 システムは、メモリ内のスペースを別に設定します その作業を行うには、その関数の。 そして、我々は、メモリのこれらのチャンクを呼び出すこと 各機能用に確保されています スタックフレームまたは関数フレームを呼び出します。 そして、あなたが期待するかもしれないとして、 これらのスタックフレーム メモリのスタック部に住んでいます。 複数の関数のスタックフレーム 所与の時点でメモリ内に存在することができます。 メインは関数moveを呼び出す場合、 そして動きは方向を呼び出し、 すべての3つの機能は、オープンフレームを持っています。 しかし、彼らはすべてのアクティブなフレームを持っていません。 これらのフレームは、スタック内に配置されています。 とからフレーム 最後に呼び出されました 関数は、スタックの一番上に常にあります。 そしてそれは、常にアクティブなフレームです。 一つはだけは本当に今までにあります 一度にアクティブです機能。 これは、スタックの一番上の1つです。 関数は、別のものを呼び出すと 関数は、それは一種の一時停止を押します。 それは一種の待って、保留されています。 また、別のスタックフレームがプッシュされます その上にスタックに。 そして、それはアクティブなフレームになります。 そして、すぐにフレーム それは待つ必要があるの下 それが再びアクティブなフレームになるまで それは、その作業を再開する前に。 機能である場合 完全な、それが行われています、 そのフレームは、スタックからポップされます。 それは専門用語です。 そして、すぐにフレーム その下に、私は言ったように、 新しいアクティブなフレームになります。 そして、それは別の関数を呼び出す場合、 それが再び一時停止になるだろう。 その新機能のスタックフレームの意志 スタックの先頭にプッシュされます。 それは、その仕事をします。 これは、バックオフポップかもしれません。 そして、他の機能 以下に、再び再開することができます。 それでは、見て、再びこの通過してみましょう 階乗関数の考えで 我々は、で定義されていること 参照するには再帰ビデオ 正確にどのようにこの背後にある魔法 再帰的な処理が行われています。 だから、これは正しい、私達の全体のファイルですか? 我々は2つ​​の定義されました 主事実functions--。 そして、私たちは想像のとおり、 任意のCプログラムが起こっています メインの最初の行で開始します。 だから私たちは主のための新しいスタックフレームを作成します。 そして、それは実行を開始するために起こっています。 メインはprintfのを呼び出します。 そして、printf関数をしようとしています 5の階乗をプリントアウト。 まあ、それは知りません。 5の何階乗で、 ので、この呼び出しは既にあります 別の関数呼び出しに応じて。 それで主は、右が一時停止しようとしています。 私はそのを残すつもりです 右が矢印、色 それと同じ色 右側のフレームを積み重ね、 主がフリーズしようとしていることを示すために、 ここでは5の階乗が呼び出されている間。 だから、5の階乗が呼び出されます。 そして、それは非常に開始するつもりです 階乗関数の始まり。 それは私が1に等しい質問AMを尋ねますか? 1に等しい5か? いや、まあ。 だから、ダウンに行くために起こっています それ以外の部分、リターンをn回 nの階乗マイナス1。 OK、まあ。 だから今、5の階乗です 別の呼び出しに応じて 渡し、階乗します パラメータとして4インチ だからの階乗 5枠、その赤枠、 右が凍結しようとしています その行に私が示されてきました そして仕上げに4の階乗を待ちます それはそのようにそれそれを行うために必要なもの 再びアクティブなフレームになることができます。 そうで4開始の階乗 階乗の始まり。 1に等しい4ですか? いいえ、それは同じことをするつもりです。 それは他のブランチを下るだろう。 これは、コードの行に到達するために起こっています。 [OK]を、私は4回を返すつもりです。 のように階乗3--のああ、階乗 4は3仕上げの階乗に依存します。 そしてそれは3の階乗を呼び出す必要があります。 そして、それはつもりが通過です 再び同じプロセス。 これは、を介して開始され、ここで取得します。 3の階乗は依存します 1の階乗に。 2開始のそう階乗、ここで取得します。 それは1の階乗に依存します。 1開始の階乗。 OK。 だから今、私たちは取得しています どこかの興味深い、右か? だから今、1は1に等しいです。 そして、私たちは1を返します。 この時点で、我々は戻ってきています。 関数は完了です。 それはの行動がありますis-- それが何をするために他に何もありません、 そのためのスタックフレーム 1ポップオフの階乗。 それは終わっています。 これは1を返しました。 そして今、2の階乗、どの すぐ下のフレームでした スタック内に、アクティブなフレームになります。 そして、それは拾うことができます 正確には、中断したところ。 これは、階乗を待っています 1の作業を終了します。 今は終了しました。 だからここではあります。 1の階乗は1の値を返しました。 2缶のだから階乗 たとえば2回1を返します。 その作業は現在行われています。 これは階乗に2を返されました それを待っていた3、の。 3の階乗は今トップフレームであり、 スタック内のアクティブなフレーム。 そしてそれは[OK]を、よく、私は行くよ、と言い 6で3回2に、戻ります。 そして、私はそれを与えるつもりです バック階乗の値 私のために待っている4、の。 私はこれで終わりです。 3の階乗は、スタックからポップし、 4の階乗は、現在アクティブなフレームです。 4 [OK]を、私は4回を返すつもりだ、と言います 6歳の3の階乗、。 それは価値があったこと 3の階乗を返します。 それで4回6は24です。 そして、私は渡すつもりです 階乗へのバック 5、私を待っされています。 5の階乗は、現在アクティブなフレームです。 これは、5回を返すために起こっています 4-- 5回24の階乗、または120-- その値を与えます バックメインに、持っています 以下のために非常に辛抱強く待っていました スタックの一番下に長い時間。 それが始めた場所、それはです。 それは、この呼び出しを行いました。 いくつかのフレームは、上部に引き継ぎました。 それはすぐに戻ってスタックの一番上にあります。 これは、アクティブなフレームです。 それで主は、値を持って120 バック5の階乗から。 それはに待っています その値をプリントアウトします。 そして、それが行われています。 メインのコードの複数行にはありません。 それでは、メインフレームはオフポップ スタックは、私たちは完了です。 そして、それは再帰がどのように動作するかです。 つまり、スタックフレームがどのように動作するかです。 これらの関数呼び出し それは以前に起こりました 待って、ちょうど一時停止にしています 後続の呼び出しのために ので、彼らがアクティブになることができます終了します 彼らは何をする必要があるか、フレームと仕上げます。 私はダグロイドです。 これはCS50です。