阶乘递归达到零时出错 为什么在Perl中,即使在C++和java?< /p>中工作,下面的递归阶乘也会失败吗?
爪哇:阶乘递归达到零时出错 为什么在Perl中,即使在C++和java?< /p>中工作,下面的递归阶乘也会失败吗?,perl,function,recursion,error-handling,parameter-passing,Perl,Function,Recursion,Error Handling,Parameter Passing,爪哇: 公共静态长阶乘(int n){ 如果(n==0){ 返回1; }否则{ 收益阶乘(n-1)*n; } } C++: 长阶乘(int n){ 如果(n==0) 返回1; 其他的 返回n*阶乘(n-1); } 但是这个在Perl中失败(使用Carp;): 子因子{ my$n=shift | | croak“参数值为空”; 如果$n==0,则返回1;#基本情况 返回$n*阶乘($n-1); } 错误消息(第10行是在main()中调用函数的位置,第16行是第二个返回语句): (由于马特·
公共静态长阶乘(int n){
如果(n==0){
返回1;
}否则{
收益阶乘(n-1)*n;
}
}
C++:
长阶乘(int n){
如果(n==0)
返回1;
其他的
返回n*阶乘(n-1);
}
但是这个在Perl中失败(使用Carp;
):
子因子{
my$n=shift | | croak“参数值为空”;
如果$n==0,则返回1;#基本情况
返回$n*阶乘($n-1);
}
错误消息(第10行是在main()
中调用函数的位置,第16行是第二个返回
语句):
(由于马特·雅各布(Matt Jacob)指出了我在原始版本中的遗漏,以下内容已被编辑。)
原始版本没有carp,但带有| | return
,错误消息为:
在./fact1.pl第16行的乘法(*)中使用未初始化值。
这是在没有命令行参数时试图使脚本保持静默的结果。(没有关于未初始化值的投诉
)
对基本情况的一个小小修改使其在Perl中也能工作:
子因子{
my$n=shift | | croak“参数值为空”;
如果$n==1,则返回1;#基本情况
返回$n*阶乘($n-1);
}
(当然,这是以放弃处理0
(零)输入为代价的。)
吸取的教训
- 在Perl代码中,它试图做的部分多于C++或java代码段(一种真正的粗略方法) 。
- 不同的错误消息应该给我一个提示
- 在
shift之后删除所有代码>
- 请记住
(零)表示0
false
Perl对于被认为是正确的东西有一些相当非正统的规则 特别是,当在布尔表达式中使用数字0时,它被认为是错误的。所以当你这么说的时候
my $n = shift || croak "null value for argument";
如果shift
将0作为参数,则它将被视为false,这意味着|
运算符需要计算其第二个操作数
幸运的是,Perl的作者预见到了这种用例,所以他们定义了一个替代的or操作符。|
检查第一个值是否真实,/
检查第一个值是否已定义
my $n = shift // croak "null value for argument";
除非
$n
可能是文本值undef
,否则这将按您的意愿执行。在这种情况下,您将需要一些更复杂的内省来检查参数是否存在,但是对于这个阶乘函数来说,这应该足够了。Perl对于被认为是真的东西有一些相当非正统的规则
特别是,当在布尔表达式中使用数字0时,它被认为是错误的。所以当你这么说的时候
my $n = shift || croak "null value for argument";
如果shift
将0作为参数,则它将被视为false,这意味着|
运算符需要计算其第二个操作数
幸运的是,Perl的作者预见到了这种用例,所以他们定义了一个替代的or操作符。|
检查第一个值是否真实,/
检查第一个值是否已定义
my $n = shift // croak "null value for argument";
除非
$n
可能是文本值undef
,否则这将按您的意愿执行。在这种情况下,您将需要一些更复杂的自省来检查参数是否存在,但对于这个阶乘函数来说,这应该足够了。回答“why not the same if/else”:java来自一个课程示例。(大括号也是如此)。C++,Perl之后的我的测试失败了。(但我喜欢去掉简单表达式的大括号)。在Perl中,等价的“无括号”解决方案是当条件子句最后出现时。在使用croak
之前,您关于错误消息的陈述与问题中的代码不匹配。如果调用factorial()
,$n
将是undef
,警告将是关于“数值等式中未初始化的$n”。(但是undef
会隐式转换为0,函数仍然会返回1。)真正的问题是:为什么要用未定义的/null值调用函数,并期望它在Perl中工作,而在其他语言中却不工作@马修:你完全正确。它不是简单的“没有”,而是带有“返回”。这是为了在没有命令行参数的情况下帮助我。(我将编辑这个问题并添加您的评论。)回答“为什么不同的if/else”:java来自一个课程示例。(大括号也是如此)。C++,Perl之后的我的测试失败了。(但我喜欢去掉简单表达式的大括号)。在Perl中,等价的“无括号”解决方案是当条件子句最后出现时。在使用croak
之前,您关于错误消息的陈述与问题中的代码不匹配。如果调用factorial()
,$n
将是undef
,警告将是关于“数值等式中未初始化的$n”。(但是undef
会隐式转换为0,函数仍然会返回1。)真正的问题是:为什么要用未定义的/null值调用函数,并期望它在Perl中工作,而在其他语言中却不工作@马修:你完全正确。它不是简单的“没有”,而是带有“返回”。这是为了在没有命令行参数的情况下帮助我。(我将编辑问题并添加您的评论。)您也可以添加/