Некоторые примечания
Используйте много пробелов, чтобы разместить свой код. Я привел в порядок код Perl в вашем вопросе, чтобы мне было легче его читать, не меняя его семантику.
Вы должны всегда use strict
и use warnings 'all'
в начале каждой программы Perl, которую вы пишете
Никогда не используйте амперсанд &
в вызове подпрограммы. В этом не было необходимости или желания со времен Perl 4 более двадцати пяти лет назад. Любой учебник, который говорит вам об обратном, неверен
Использование <>
в контексте списка (например, в качестве параметров вызова подпрограммы) прочитает весь файл и исчерпает дескриптор файла. После этого любые вызовы <>
будут возвращать undef
Вы должны использовать chomp
для удаления новой строки из каждой строки ввода
Вы объявляете $mymax
в рамках подпрограммы max
, но затем пытаетесь напечатать его в print_stat
, где его нет. use strict
и use 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
person
Borodin
schedule
09.07.2016
<>
читается до EOF (возвращая каждую строку, прочитанную как отдельную строку). Второе использование<>
ничего не возвращает, так как первое уже считано в EOF. если вы хотите передать значения, возвращаемые при первом использовании<>
, двум разным подпрограммам, вам нужно их где-то сохранить. - person ikegami   schedule 09.07.2016use strict; use warnings 'all';
- person ikegami   schedule 09.07.2016&
перед вызовом подпрограммы (если только это не одна из крайне редких ситуаций, когда вы на самом деле хотите переопределить прототип подпрограммы). - person ikegami   schedule 09.07.2016List::Util
, который имеетmax, min, sum
методов. В среднем всегоsum / count
. perldoc.perl.org/List/Util.html - person xxfelixxx   schedule 09.07.2016$foo
в своей функции, но забыли объявить ее, это обычно является ошибкой, но молча делает неверную вещь, если ваш основной код также использует переменную с именем$foo
. - person melpomene   schedule 09.07.2016