【问题标题】:Why is my Perl loop off by one at the end?为什么我的 Perl 在最后循环了一个?
【发布时间】:2011-04-29 15:13:50
【问题描述】:

我有这个程序没有按预期工作。帮帮我。

我想打印一个行标题。

如果输入是4,我希望输出1|2|3|4

如果我硬编码$count 值,它就不能正常工作,但最后一个数字不见了。

sub printC {
        my $count = @_;
        # count = 4  # works partially only prints 1|2|3
        for(my $i=1;$i<$count;$i++) {
                print "$i|";
        }
        print $i;
}
$count  = 2;
&printC($count);
print "\n";

【问题讨论】:

    标签: arrays perl subroutine


    【解决方案1】:

    问题出在这里:

    my $count = @_;
    

    分配发生在 标量 上下文中,它将数组@_ 中的元素数分配给$count,您的情况是1,因为您正在传递1 参数到函数。

    要解决此问题,您可以这样做:

    my ($count) = @_; 
    

    my $count = $_[0];
    

    这是另一个问题:

    for(my $i=1.....
        ^^
    

    通过使用my,您已将$i 本地 设置为for 的主体,并且它在其外部 将不可用。因此,for 之外的最终print 没有打印任何内容。要解决此问题,请将 $i 的声明移到循环外:

    sub printC {
            my ($count) = @_;
            my $i;
            ....
    

    始终把写作作为重点

    use strict;
    

    在程序的顶部,它使您能够捕获此类错误。

    perl 方法执行你的函数的操作是:

    print join('|',1..$count);
    

    【讨论】:

      【解决方案2】:

      一个真正的 Perl 黑客可能会这样写:

      sub printC {
        my $count = shift;
        print join "|", (1 .. $count);
      }
      

      一旦您了解了它的工作原理,您就会发现您对 Perl 有了更多的了解。 :-)

      【讨论】:

        【解决方案3】:

        一旦您离开 for 循环,$i 将不存在,因为它的声明位置。

        你可以这样做

        sub printC {
            my ($count) = @_;
            my $i;
            for ($i = 1; $i < $count; $i++) {
                print "$i|";
            }
            print $i;
        }
        

        更简单:

        sub printC {
            my ($count) = @_;
            print join("|", 1 .. $count) . "\n";
        }
        

        【讨论】:

          【解决方案4】:

          另外一点“更加 Perlish”是不使用 C 风格的 for 循环。在 Perl 中几乎从不需要使用 C 风格的 for

          而不是

          for(my $i=1;$i<$count;$i++) { ... }
          

          使用

          for my $i (1 .. $count) { ... }
          

          它们几乎是等价的,除了后一个版本更容易阅读并且更能抵抗一个错误的错误。 (您的代码只打印1|2|3 而不是1|2|3|4 的原因是因为您的C 风格for 中的测试在检查$i&lt;$count 时应该是$i&lt;=$count - 这是C 中一个非常常见的错误-style for 循环,for (list) 完全避免。)

          另外,不要在子呼叫前加上&amp;。它是 Perl 4 的保留,在 Perl 5 中不再需要它,并且具有您可能不知道也可能不想要的副作用。只需使用printC($count) 而不是&amp;printC($count)

          但是,是的,在这种特殊情况下,join 可能是比for 更好的方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多