Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
阶乘递归达到零时出错 为什么在Perl中,即使在C++和java?< /p>中工作,下面的递归阶乘也会失败吗?_Perl_Function_Recursion_Error Handling_Parameter Passing - Fatal编程技术网

阶乘递归达到零时出错 为什么在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
  • 从5.10版开始,Perl中就存在
  • 关于正确的错误处理,本文提供了一个很好的概述

  • 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中工作,而在其他语言中却不工作@马修:你完全正确。它不是简单的“没有”,而是带有“返回”。这是为了在没有命令行参数的情况下帮助我。(我将编辑问题并添加您的评论。)您也可以添加
    /