Perl语言入门 (08 自定义函数)

2016-09-12 19:13:09来源:CSDN作者:haoweilaizoule人点击

由于公司需要,本人最近在学习Perl这种脚本语言,本文是我在学习Perl的过程中总结出来的一些心得和笔记,希望能够帮助也在学习Perl的各位同僚。废话不多说直接上干货!!!

————————————————— 干货分割线 —————————————————

Pe r l中,用户定义的函数称为子例程.子例程可以在任何位置被调用,包括在其他子例程中调用.

创建函数:

sub 函数名{

代码语句;

...

代码语句;

}

Exp:

sub yesno{

Print “R U sure?”;

$answer = <STDIN>;

}

调用子例程的两种方法:

1.$yesno();  #任何位置都可以使用该方法

2. yesno();  #代码中已经声明了子例程可以使用该方法.

 

Exp:

sub countdown{

for($i = 10; $i >=0; $i--){

print “$i  -”;

}

}

Print “T-minus:”;

Countdown();

Print “Blastoff”;

 

子例程的返回值:子例程的返回值是它的内部计算的最后一个表达式的值或者是return语句显示返回的值.

Exp:

1.不用return关键字:

Sub two_by_four{

2*4; #此处与Java不同,可不写return关键字;

}

Print 8 * two_by_four();  #输出 64;

 

2.使用return关键字:

当程序需要在子例程结束前返回,或当想要知道返回的是什么值,而不是想要执行到最后表达式的值时,就需要使用r e t u r n语句。

Exp:

My $x = 70;

If(x_greaterthan100()){

Print “$x is greater than 100/n”;

}else{

Print “子例程返回为0.所以在if中无输出/n”;

}

Sub x_greaterthan100{

Return(1) if($x > 100);

0;

}

PS:最好把子函数写在父函数后面,这样在传递参数时便不会提示警告.

 

子例程能够返回数组和哈希结构,也能返回标量.

Exp:

#!/usr/bin/perl  

use strict;  

use warnings;

 

my @a = shift_to_upper();

for(my $i = 0; $i <= $#a; $i++){

print "$a[$i]/n";

}

 

sub shift_to_upper{

my @words = qw(cia fbi un nato unicef);

foreach(@words){

$_ = uc($_);  #小写转化为大写

}

return (@words);

}

 

子例程传递参数的写法:

Subname(arg1,arg2,arg3);

Subname arg1,arg2,arg3; #该子例程被定义后,才能使用该写法

$subname(arg1,arg2,arg3);

 

在写子函数时,有两种写法:

1. Sub subroutine($$){},该方法要求在调用该方法时必须传递两个参数;

2. sub subroutine(){},该方法对传参个数没有严格要求。

 

在子例程中,被传递的参数可以通过P e r l的特殊变量@ 来访问。下面这个代码段显示了为函数传递参数(3个字符串直接量)和输出参数的情况:

#!/usr/bin/perl

  

use strict;  

use warnings;

 

sub printargs{

print join(',',@_);  #参数通过@_传递过来(3个字符串直接量)

}

printargs('aaa','bbb','ccc ddd');

输出:aaa,bbb,ccc ddd

 

use strict;  

use warnings;

 

sub display_box_score{

(my $hits,my $at_bats) = @_;    #  =@_;  为固定写法,只要注意传递的参数个数即可

print "这里的hits为:$hits/n";

print "这里的at_bats为:$at_bats/n";

}

display_box_score(50,210);

PS:

1.当参数为1个时,输出为:

 

因为at_bats没有参数,所以报错;

2.当参数个数>2时,不影响程序结果,只是后面的参数没有接收到而已

3.@ _包含了传递给子例程的原始参数的别名。如果修改了@ _(或者修改了@ 的任何元素),就会修改参数列表中的元素变量。

 

传递数组和Hash结构

1.一个参数时

@sorted_items = sort_numberically(@items);

Sub sort_numberically{

Print “sorting …”;

Return (sort{$a ó $b} @_);

}

PS:在该子例程中,@items通过@_进行引用

 

2.多个参数时

Exp:

Display_arrays(@first,@second);

Sub Display_arrays{

(@a,@b) = @_;

Print “The first array:@a/n”;

Print “The second array:@b/n”;

}

输出:The first array:[@_的全部值]

报错

The second array:[空值]

PS: @b并不会得到参数;

3.参数为标量和Hash时:

参数为混合体时,只要标量在参数列表中首先被传递,且知道有多少个标量。

Exp:

Sub lots_of_args{

($first,$second,%hash) = @_;

}

lots_of_args($foo,$bar,%myhash);

作用域:

Exp1:

$weight = 150;

Print moonweight;

Sub moonweight{

Return ($weight/6);

}

PS:

缺点:全局变量$weight传递给子函数,且必须确保正确设置$weight.

Exp2(升级版):

Print moonweight(150);

Sub moonweight{

($weight) = @_;

Return ($weight / 6);

}

PS:

优点:不必设置外部变量,将参数自然而然传递给子函数内部。

 

函数嵌套调用的例子:

#!/usr/bin/perl  

#use strict;  

#use warnings;

 

print "please enter data,separated by commas:/n";

my ($data,@dataset);

$data = <STDIN>; chomp $data; #从终端输入放入标量中

@dataset = split(/[/s,]+/,$data); #将标量按照某种格式分割,放入数组  /[/s,]+/:匹配多个空格或,

 

print "Median:",median(@dataset),"/n";

print "Mean:",mean(@dataset),"/n";

print "Standard Dev.:",std_dev(@dataset),"/n";

 

#求数组中元素的个数

sub mean{

my (@data) = @_; #从外部接受数据时定义的标量加()

my $sum;

foreach(@data){

$sum += @_;dsf

}

return ($sum / @data);

}

 

#返回数组中间的数,若为偶数,则返回两个数的平均值

sub median{

my (@data) = sort {$a <=> $b} @_;  #将原数组重新排序

if(scalar (@data) % 2){

return ($data [@data / 2]);  #@data/2的返回值向上取整

}else {

my ($upper ,$lower);

$upper = $data[@data / 2];

$lower = $data[@data / 2 -1];

return (($lower+$upper) / 2);

}

}

 

sub std_dev{

my (@data) = @_;

my ($sq_dev_sum,$avg) = (0,0);

$avg = mean(@data);

foreach my $elem(@data){

$sq_dev_sum += ($avg - $elem) ** 2;

}

return (sqrt($sq_dev_sum / @data - 1));

}

 

声明Local变量:

Exp:

Sub myfunc{

Local($foo) = 56;

}

local声明的变量和用my几乎相同。差别是:声明为局部变量的那些变量,可以在它的作用域范围内的代码块中看到,也可以在从该代码块中调用的任何子例程中看到。基本都用my生命而不用local.

 

 

 


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台