没有输出值

时间:2016-07-08 23:28:13

标签: perl subroutine

我在编写第一个Perl程序时出现问题。

我在这里要做的是使用每个值的子程序获取数字列表的最大值,最小值,总数和平均值,并使用另一个子例程来打印最终值。我正在为所有变量使用“私有”,但我仍无法打印我的值。

这是我的代码:

&max(<>);

&print_stat(<>);

sub max {

    my ($mymax) = shift @_;

    foreach (@_) {

        if ( $_ > $mymax ) {
            $mymax = $_;
        }
    }

    return $mymax;
}

sub print_stat {

    print max($mymax);
}

2 个答案:

答案 0 :(得分:0)

请尝试这个:

use strict;
use warnings;

my @list_nums = qw(10 21 30 42 50 63 70);
ma_xi(@list_nums);

sub ma_xi
{
    my @list_ele = @_;
    my $set_val_max = '0'; my $set_val_min = '0';
    my $add_all_vals = '0';
    foreach my $each_ele(@list_ele)
    {
        $set_val_max = $each_ele if($set_val_max < $each_ele);
        $set_val_min = $each_ele if($set_val_min eq '0');
        $set_val_min = $each_ele if($set_val_min > $each_ele);
        $add_all_vals += $each_ele;
    }

    my $set_val_avg = $add_all_vals / scalar(@list_ele) + 1;

    print "MAX: $set_val_max\n";
    print "MIN: $set_val_min\n";
    print "TOT: $add_all_vals\n";
    print "AVG: $set_val_avg\n";

    #Return these values into array and get into the new sub routine's

}

答案 1 :(得分:0)

一些注释

  • 使用大量空格来布置代码。我已经在您的问题中整理了Perl代码,以便我可以更轻松地阅读它,而无需更改其语义

  • 您必须总是 use strictuse warnings 'all'位于您编写的每个Perl程序的顶部

  • 从不在子程序调用中使用&符号&。自二十五年前的Perl 4以来,这一点并非必要或可取。任何告诉你的教程都是错误的

  • 在列表上下文中使用<>(例如子程序调用的参数)将读取所有文件并耗尽文件句柄。此后,对<>的任何来电都将返回undef

  • 您应该使用chomp从每行输入中删除换行符

  • 您在$mymax子例程的范围内声明max,但然后尝试在不存在的print_stat中打印它。 use strictuse warnings 'all'会为您发现错误

  • 您的max子例程返回其计算的最大值,但您从不使用该返回值

以下是您的代码的固定版本。

请注意,我已将整个文件读入数组@values,然后立即将它们全部删除。一般来说,最好一次读取和处理一行输入,这在这里很有可能,但我想说尽可能接近原始代码

我还在变量max中保存了$max的返回值,然后将其传递给print_stat。尝试再次读取文件并将所有这些值传递给print_stat是没有意义的,正如您的代码所做的那样

我希望这会有所帮助

use strict;
use warnings 'all';

my @values = <>;
chomp @values;

my $max = max(@values);
print_stat( $max );

sub max {
    my $mymax = shift;

    for ( @_ ) {
        if ( $_ > $mymax ) {
            $mymax = $_;
        }
    }

    return $mymax;
}

sub print_stat {
    my ($val) = @_;

    print $val, "\n";
}


更新

这是一个计算您提到的所有统计信息的版本。在这种情况下,我不认为子例程是一种帮助,因为解决方案很短并且没有代码可重用

请注意,我在__DATA__之后添加了程序文件末尾的数据,这样我就可以从DATA文件句柄中读取数据了。这对于测试来说通常很方便

use strict;
use warnings 'all';

my ($n, $max, $min, $tot);

while ( <DATA> ) {

    next unless /\S/; # Skip blank lines

    chomp;

    if ( not defined $n ) {
        $max = $min = $tot = $_;
    }
    else {
        $max = $_ if $max < $_;
        $min = $_ if $min > $_;
        $tot += $_;
    }

    ++$n;
}

my $avg = $tot / $n;

printf "\$n   = %d\n",   $n;
printf "\$max = %d\n",   $max;
printf "\$min = %d\n",   $min;
printf "\$tot = %d\n",   $tot;
printf "\$avg = %.2f\n", $avg;


__DATA__
7
6
1
5
1
3
8
7

输出

$n   = 8
$max = 8
$min = 1
$tot = 38
$avg = 4.75