#!/usr/bin/perl -w
#创建子程序检查$values的值
sub printOK
{
if($values>10){
print "Values is $values.\n";
}
else {
print "Value is too small.\n";
}
}
$values=15;
printOK;


在默认情况下Perl变量在全局范围内有效,因此可以在子程序printOK内部变量引用变量$values。变量的范围指可以引用变量的程序代码部分。使用关键字local和my关键字来创建变量,这种变量的范围完全限于类似printOK这样的子程序内部。这种局部变量的范围完全限于子程序,这意味着它们可以和全局变量具有相同的名称,但根本不会影响全局变量的值。


sub printOK
{
my $localvalues=$values;
if($localvalues>10){
print "Values is $values.\n";
}
else {
print "Value is too small.\n";
}
}
$values=15;
printOK;
$values=8;
printOK ($values);


向子程序传递值时,那些值存储在特殊的perl数组@_中,可以在子程序内部访问这个数组。下面例子使用shift函数从@_数组得到传递给printOK的值:


sub printOK
{
my $localvalues=shift(@_);
if($localvalues>10){
print "Values is $values.\n";
}
else {
print "Value is too small.\n";
}
}
$values=15;
printOK($values);#使用函数时必须使用这种方式
$values=8;
printOK ($values);



返回值:除了接收传递的值之外,子程序也可以返回值,下面的例子使用return函数从子程序返回传递的两个值之和从子程序返回值取代了子程序本身的名称,而且在print语句中直接连接在字符串内:


sub addem
{
($value1,$value2)=@_;
return $value1+$value2;
}
print "2+2=".addem(2,2)."\n";


perl和其他语言不一样,在perl中,不需要再使用子程序之前的声明,除非在没有将参数包围在括号的情况下使用子程序,这中情况下,必须在使用之前声明或者定义子程序。perl中声明子程序的不同方法:


sub SUBNAME;
sub SUBNAME(PROTOTYPE);
sub SUBNAME BLOCK;
sub SUBNAME(PROTOTYPE) BLOCK;


从perl程序包中导入子程序:


use packagename qw(subname1 subname2 subname3);


子程序也有前缀反引用符号,使用反引用符号是可选的。子程序的反引用符号是:&,出现在每个子程序名称开头的&字符是名称的隐含组成部分,可以忽略它。如果希望在addem的时候不添加括号:

方法一是在使用addem之前声明

sub addem;
$value3=addem 2,2;
print "2+2=$value3\n";
sub addem
{
($value1,$value2)=@_;
return $value1+$value2;
}


方法二:在使用子程序之前定义子程序:


sub addem
{
($value1,$value2)=@_;
return $value1+$value2;
}
print "2+2=".addem 2,2;
print "\n";


使用子程序原型


perl学习笔记-----------------------(15)_perl函数定义


定义子程序


sub SUBNAME BLOCK
sub SUBNAME (PROTOTYPE) BLOCK;
sub Fprinthello
{
print "Hello!\n";
}
Fprinthello;调用printhello函数打印hello
printhello();声明子程序
sub printhello
{
print "Hello!\n";
}



perl中调用子程序的方法:

1.使用子程序前缀反引用符号&:&subname(argumentlist)

2.使用括号,&是可选的:subname(argumentlist)

3.预先声明子程序,或者从程序包中导入子程序,或者在代码中已经定义子程序,则可以忽略括号:subname argumentlist;

4.将子程序名称存储在数量中,并称之为&$scalar:


$scalar=subname;
&$scalar(argumentlist);

使用不同的方法调用addem函数:


$value=&addem(2,3);
print "Use &addem(2,3) :$value\n";
$value=addem(2,4);
print "Use addem(2,4):$value\n";
$value=addem 2,3;
print "Use addem 2,3:$value\n";
$name="addem";
$value=&$name(2,5);
print "use \&\$name(2,5):$value\n ";


调用之前检查子程序是否存在:

在调用子程序之前,可以通过内置的perl的defined函数来检查它是否存在:


@_=(2,8);
$value=&addem if defined addem;#用defined函数判定是否存在addem函数,如果存在将addem计算的结果值赋给$value
print "for \@\_=(2,8) in (\$value=\&addem if defined addem)=$value\n";

perl v5.6.0版本,可以使用exists来检查是否定义了子程序:


@_=(2,10);
$value=&addem if exists &addem;#用exists函数判定是否存在addem函数,如果存在将addem计算的结果值赋给$value
print "for \@\_=(2,10) in (\$value=\&addem if exists \&addem)=$value\n";


如果编写的代码将被其他人复制到他们的应用程序中,在调用子程序之前检查是否定义了子程序是非常用用的



读取传递给子程序的参数:

1.可以在子程序中的代码中使用特殊数组@_读取传递给子程序的参数。这个数组专门用于保存传递给子程序的参数。

2.如果像子程序传递了两个传递了两个参数,则子程序的代码可以用$_[0]和$_[1]的形式来得到参数的值。

用子程序addem加两个数字,并打印结果,用addem(2,6)的形式来使用这个子程序。


sub addem1
{
$value1=$_[0];
$value2=$_[1];
print "\$value1+\$value2=".($value1+$value2)."\n";
}
addem1(2,6);


从@_中获取值的方法和使用数组的方法一样。用shift函数从@_中获取值:

sub addem2 
{
$value1=shift @_;
$value2=shift @_;
print "Use \shift \@\_ \$value1+\$value2=".($value1+$value2)."\n";
}
addem2(10,5);


子程序中默认shift使用@_,上方代码可以这样:


sub addem3 
{
$value1=shift;
$value2=shift;
print "Use \shift in \$value1+\$value2=".($value1+$value2)."\n";
}
addem3(10,8);


使用列表赋值来一次得到@_中的所有值:


sub addem4 
{
($value3$value4)=@_;
print "Use\(\$value3,\$value4\)=\@\_ in \$value3+\$value4=".($value3+$value4)."\n";
}
addem4(10,10);


PS:当向子程序传递标量时,它们按引用传递,实际传递了标量值的引用(标量引用的作用类似存储在内存中的标量地址)。当修改传递的值时,也修改了传递这个值的最初代码的那个值。增加传递给子程序addone的值(传递的值¥value将增加):


sub addone
{
++@_[0];
}
$value=1;
addone($value);
print "Use \+\+\@\_\[0] in addone(\$value):$value\n";


增加数组中每个元素的值,并返回增加值以后的数组:


sub addone_1
{
foreach $_(@_){
$_++;
}
return @_;
}
@b=(1,2,3,4,5,6,7,8,9,10);
@b_addone=addone_1(@b);
print join (" ,",@b_addone);
print "\n";