我刚开始学习Perl并且在迭代计算阶乘方面遇到了麻烦。
使用此代码我收到错误:
在void上下文中无用的私有变量
sub factorial {
my ($input) = @_; #assigning argument
for ( $input; $input > 0; $input -= 1 ) {
my $factorial = $input * ($input -1);
return $factorial;
}
}
有人知道那里出了什么问题吗?
答案 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;
}