0

Perl で階乗 N を計算する再帰的な実装があります。

sub fact {
  my ($n) = shift;
  return $n if $n <= 2;
  return $n * fact($n - 1);
}

関数が結果を返す前に Perl が中間結果を保持する場所を誰か説明してもらえますか?

UPDと、デバッガーを使用するか、他のものを使用してそれらを表示するにはどうすればよいですか?

回答から、この値はスタックに保持されると説明されましたが、スタックからこれらの値を確認するにはどうすればよいですか?

4

4 に答える 4

2

再帰を使用すると、各呼び出しで渡される引数はすべて、呼び出しフレーム/スタックに配置されます。Carp&cluckを使用すると、コールフレームを確認できます。中間結果は、スタックがベースケース($ v == 1)に到達したときに巻き戻される間に計算されます。CPUレジスタのみにあるのでしょうか?そして、演算子(*)は、この中間結果にスタック上の$vを乗算します。この記事もチェックしてください。

#!/usr/bin/env  perl

use strict;
use IO::Handle;
use Carp qw(cluck);

STDOUT->autoflush(1);
STDERR->autoflush(1);

sub factorial {
    my $v = shift;

    dummy_func();
    return 1 if $v == 1;
    print "Variable v value: $v and it's address:", \$v, "\ncurrent sub factorial addr:", \&factorial, "\n","-"x40;
    return $v * factorial($v - 1);
}

sub dummy_func {
    cluck;
}

factorial(5);

また、デバッグモードで実行すると役立ちます。

perl -d factorial.pl

于 2013-02-21T01:31:52.550 に答える
2

によって返されるスカラーは$n、スタックに格納されます。

を呼び出す直前のスタックは次のようになりますfact

  • $n再帰レベル 0 で返されるスカラー
  • リスト:
    • $n再帰レベル 1 で返されるスカラー
    • リスト:
      • $n再帰レベル 2 で返されるスカラー
      • リスト:
        • $n-1再帰レベル 2 で返されるスカラー
        • \&fact再帰レベル 2 で返されるスカラー

を呼び出した直後のスタックは次のようになりますfact

  • $n再帰レベル 0 で返されるスカラー
  • リスト:
    • $n再帰レベル 1 で返されるスカラー
    • リスト:
      • $n再帰レベル 2 で返されるスカラー
      • fact($n - 1)再帰レベル 2 で返されるスカラー

この時点で、乗算演算子はスタックの最後の 2 つの値を乗算し、結果をスタックに配置します。

  • $n再帰レベル 0 で返されるスカラー
  • リスト:
    • $n再帰レベル 1 で返されるスカラー
    • リスト:
      • $n * fact($n - 1)再帰レベル 2 で返されるスカラー

その後、サブが返され、

  • $n再帰レベル 0 で返されるスカラー
  • リスト:
    • $n再帰レベル 1 で返されるスカラー
    • fact($n - 1)再帰レベル 1 で返されるスカラー

等々。

于 2013-01-01T17:19:17.200 に答える
1

関数内のローカル変数と同様に、呼び出しの中間結果はスタックに保持されます。

return $n * fact($n - 1);

は次と同等に処理されます。

my $temp = fact($n - 1);
return $n * $temp;

更新: 製品を返品する前に、製品がどこに保持されているかについても関心があるようです。これもスタック上の一時的なものであるため、次と同等です。

my $temp1 = fact($n - 1);
my $temp2 = $n * $temp1;
return $temp2;
于 2013-01-01T00:51:00.007 に答える
1

$nは として宣言されているためmy $n、レキシカル スコープの変数であり、システム テーブルではなくスタックに格納されます。詳細については、my() による Perl 変数を参照してください。

于 2013-01-01T01:55:15.090 に答える