计算阶乘的子程序错误:在void上下文中无用的私有变量

时间:2017-04-20 16:38:02

标签: perl

我刚开始学习Perl并且在迭代计算阶乘方面遇到了麻烦。

使用此代码我收到错误:

  

在void上下文中无用的私有变量

sub factorial {
    my ($input) = @_; #assigning argument

    for ( $input; $input > 0; $input -= 1 ) {
        my $factorial = $input * ($input -1);
        return $factorial;
    }
}

有人知道那里出了什么问题吗?

2 个答案:

答案 0 :(得分:1)

for (A; B; C) { ... }

基本上是

A;
while (B) { ... } continue { C }

所以你正在评估以下内容:

$input;

这没有任何效果,所以Perl警告你,你可能不是故意这样做的!

你的循环毫无意义!你总是返回第一次通过。更糟糕的是,当$input为零时,您不会返回任何有意义的内容!

sub factorial {
    my ($n) = @_;
    my $accumulator = 1;
    for (; $n>0; --$n) {
       $accumulator *= $n;
    }

    return $accumulator;
}

在Perl中很少有任何理由使用C风格的循环。以下更清楚:

sub factorial {
    my ($n) = @_;
    my $accumulator = 1;
    for my $i (2..$n) {
       $accumulator *= $i;
    }

    return $accumulator;
}

sub factorial {
    my ($n) = @_;
    my $accumulator = 1;
    $accumulator *= $_ for 2..$n;
    return $accumulator;
}

答案 1 :(得分:0)

$input中的变量(声明)for ($input; ...)没有任何意义,也没有任何作用。通过将use diagnostics;添加到程序的顶部,您将获得

  

在t.pl第19行(#1)的void上下文中无用的私有变量       (W void)你做了一些没有副作用的事情       没有任何返回值,[...]

您也可以通过

查看并直接修复此问题
for (my $input = shift; $input > 0; $input -= 1) {

my ($input) = @_;
for (; $input > 0; $input -= 1) { ...

但其余部分不正确,因为$factorial在每次交互时都被重新声明,然后你马上回来。因此,将声明部分(my $factorial;)移到循环之前,并将return移动到循环之后。然后,您的代码可以使用 - 除了0,其中因子需要1

还有其他方法,例如

sub factorial {
    my ($input) = @_;
    my $factorial = $input || 1              # 0! == 1
    $factorial *= $input while --$input > 1;
    return $factorial;
}

或“标准”递归方式

sub factorial {
  my ($input) = @_;
  return 1 if $input == 0;
  return factorial($input-1) * $input;
}