加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl子程序

发布时间:2020-12-15 21:05:01 所属栏目:大数据 来源:网络整理
导读:1.定义一个子程序 要定义自己的子程序,使用关键字sub,子程序的名字(无这个符号),组成子程序的缩进的代码块(花括号中),如: sub marine { $n + = 1; #全局变量$n print“Hello,sailor number $n!n”; } 子程序的定义是全局的;没有某些强大的技巧,Perl

1.定义一个子程序

要定义自己的子程序,使用关键字sub,子程序的名字(无&这个符号),组成子程序的缩进的代码块(花括号中),如:

sub marine {
$n + = 1; #全局变量$n
print“Hello,sailor number $n!n”;
}

子程序的定义是全局的;没有某些强大的技巧,Perl中没有私有子程序(private subroutines)◆。如
果两个子程序有相同的名字,那后一个将覆盖前一个◆。这被看作是一种不好的编成习惯,它将迷惑你的维护人员。

2.调用子程序

可以使用子程序的名字(带有&)来调用子程序◆:

&marine; #输出Hello,sailor number 1!
&marine; #输出Hello,sailor number 2!
&marine; #输出Hello,sailor number 3!
&marine; #输出Hello,sailor number 4!
通常,我们说调用(invocation)是指调用子程序(call the subroutine)。

3.返回值

子程序可以被某个表达式调用,无论此表达式的值是否被利用。如早些的例子&marine,我们得到此表达式的值,但其值被
扔掉了。
许多时候,当调用某个子程序时,需要使用其返回值。这意味着应当注意子程序返回值。所有的Perl子程序都会返回值,
在Perl中返回值和不返回值是没有区别的。当然,不是所有Perl子程序返回的值都是有用的。

由于所有的被调用的子程序都要返回值,因此使用特殊的返回值语法在大多数情况下是一种浪费。因此Larry将之简化了。
当Perl遍历此子程序时,将会计算每一步的值。此子程序中最后计算的值将被返回。

例如,下面的子程序:
sub sum_of_fred_and_barney{
print“Hey,you called the sum_of_fred_and_barney suroutine!n”;
$fred + $barney; #返回值
}

子程序中最后一个被计算的表达式为$fred + $barney,因此$fred 和$barney的和将被返回。下面是一些调用代码:
$fred = 3;
$barney = 4;
$wilma = $sum_of_fred_and_barney; #$wilma 得到7
print“$wilma is $wilma.n”;
$betty = 3 * &sum_of_fred_and_barney; #$betty得到21
print“n$betty is $betty.n”

上述print语句是用于调试的,从它可以看到子程序被调用了。当程序调试好后,应当把它们去掉。假设在上述子程序中加
入了下面的一行代码:
sub sum_of_fred_and_barney{
print“Hey,you called the sum_of_fred_and_barney subroutine!n”;
$fred + $barney; #其值不会被返回
print“Hey,I’m returning a value now!n”; #oops!
}
在上述例子中,最后一个被计算的表达式不是$fred + $barney;而是print 语句。其返回值通常为1,意思是“print was
succfessful(打印成功)”◆;但这不是你想要的返回值。因此当向子程序加入新的代码时要小心些,因为返回值为最后一
个被计算的表达式。

因此,第二个子程序中$fred+ barney的值去哪里了呢?由于没有把它存放在任何地方,Perl将它丢弃了。如果打开了警告,
Perl(注意到两个变量相加但其值未被使用)可能给出如下的警告信息“a useless use of addition in a void context.”术语void
context 是说其值未被存于变量或者被别的方式使用。

4.参数

$n = &max(10,15); #此子程序有2个参数

此参数列表被传到子程序中;这些参数可以被子程序使用。当然,这些参存放在某个地方,在Perl中,会自动将此参数列
表(此参数列表的另一个名字)自动存放在一个叫做@_的数组中。子程序可以访问次数组变量来确定此参数的个数以及
其值。

这也就是说此子程序参数的第一个值存放在$_[0]中,第二个存放在$_[1],依次类推。但必须强调的是这些变量和$_这个
变量没有任何关系,如$dino[3](数组@dino的一个元素)和$dino的关系一样。这些参数必须存放在某个数组变量中,而Perl
存放在@_这个变量中。

5.子程序中的私有变量

默认情况下,Perl中所有变量都是全局的;也就是说,这些变量可以在程序的任意部分使用。你也可以任意时候使用my
创建私有变量:
sub max {
my($m,$n); #新的,私有变量
($m,$n) = @_; #赋值
if($m > $n) {$m} else{$n}
}

6.参数列表的长度

当然,子程序可以容易的检测@_是否含有恰当的个数。例如,我们可以如下的书写&max◆:

sub max{
if(@_!=2){
print“WARNING! &max should get exactly two arguments!n”;
}
#continue as before….
.
.
.
}

6.1更好的&max程序

现在重写&max,使它可以在任意参数个数下都能正常工作:
$maximum = &max(3,5,10,4,6);
sub max {
my($max_so_far) = shift @_;
foreach (@_){
if($_>$max_so_far){
$max_so_far=$_;
}
}
$max_so_far;
}

这段代码使用了一种叫做high-water mark的算法:洪水之后,会在岸边留下痕迹。最高处的标记,表明了到达的最高水位。
在此程序中,$max_so_far记录最高的水位。第一行中置$max_so_far为3(第一个参数),它是从参数数组:@_中移出来的。
此时,@_变成了(5,10,4,6),因为3已被移出。此时出现过的最大数为3。

现在,foreach 循环遍历@_剩下的值。循环中的控制变量是默认变量$_。(请记住,$_和@_没有任何关系;它们名字相同

完全是巧合)。

6.2空参数列表

经过改进后的&max有了很大的提高,其参数可以不是2个。但,如果参数个数为0,会发生什么情况呢?
初次遇到这个问题时,可能认为其过于深奥。毕竟,谁会调用&max而不给其参数呢?但是,某人可能如下书写:
$maximum = &max(@numbers);
而@numbers可能为空,例如可能从空文件读入。因此,你需要知道,&max此时会怎样处理呢?
子程序第一行将@_的第一个元素赋给$max_so_far。这不会有什么坏影响;数组为空,shift操作返回undef给$max_so_far。
现在进入foreach循环体,由于为空,循环体一次都不执行。
现在,Perl 返回$max_so_far的值undef。在某种意义下,这是正确的答案,因为空表中没有最大的元素。
当然,当调用此子程序时注意返回值可能为undef,或者保证调用的参数非空。

7.my变量的注释

这些局部变量可以在任意块中使用,不仅仅是子程序中。例如,可以在if,while,foreach等块中使用:
foreach (1..10){
my($square) = $_*$_; #本循环中的私有变量
print “$_ squared is $squrare.n”;
}
变量$square是私有的,仅在此块中可见;在本例中,此块为foreach循环块。如果没有大括符({}),它将是整个文件中的
私有变量。到现在为止,你的程序不会超过一个文件,因此不讨论这个问题。只有和它处于一个代码块中的语句才能使用
它。这非常有利于代码的维护,如果$square值错了,则其被限制在相应的代码段中。有经验的程序员(通常是通过辛苦的
实践)发现将变量的作用域限制在一页,或者几行代码中,能加速开发和测试。当然,my操作不会改变赋值参数的context:
my ($num) = @_; #列表context,同($sum) = @_;
my $num = @_; #标量context,同$num = @_;

在第一个例子中,$num得到第一个参数,因为其在列表context中;第二个例子中,将得到参数的个数,因为是在标量context
中。两条语句都可能是正确的;不能仅凭它来判断是否使用错误,因此Perl不能提示(warning)你,如果你使用错误。(当
然,不能将这两天语句写在同一个子程序中,因为不能在一个作用域内重复定义某个变量)。当读到这样的代码时,可以通
过上下文来判断其context。

记住,如果没有使用括号,my仅定义一个变量◆:

my $fred,$barney; #错误!没有定义$barney
my ($fred,$barney); #两个均定义了

当然,可以使用my创建新的,私有数组◆:

my @phone_number;
如果新的变量没被赋值的话:标量变量会自动赋与undef,而数组变量会赋与空列表。

8.使用strict Pragma

Perl是一种宽容的语言◆。你可能希望Perl严格一些;那可以使用strict pragma。

pragma可以提示编译器,告诉它一些关于这块代码的信息。如,使用strict pragma告诉Perl的编译器,应当严格的检查这段代码。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读