您好,欢迎访问三七文档
第五章子程序刘融华中农业大学生物信息中心子程序的定义和分类子程序也称为函数,即执行一个特殊任务的一段分离的代码,它可以减少重复代码且使程序易读。函数可分为系统函数和用户函数。系统函数为程序语言自带的函数,perl中包括print、chomp、reverse、sort等;用户函数则是程序员依据个人需求所编写的子程序。子程序的优点子程序把长的程序脚本分解成小的更易理解的片断,这方便了调试,使查找错误更简单。子程序把常用操作封装为独立的单元,真正实现代码重用。程序员可以维护一个自己的常用程序操作库,需要时直接调用,十分方便。子程序一次创建便可多次使用。因此,如果将来需要更新代码,只要修改特定部分(字程序定义处),子程序调用处无需更改。子程序的定义可以在程序的任意位置,其格式如下:sub子程序名{语句块;}$world=‘world’;subtest{print“Hello,$world\n”;}注意:1)Perl子程序中的变量默认为全局变量,与其他程序共享。2)如果两个子程序同名,那么后一个将覆盖前一个。子程序的格式调用子程序通过在子程序前加“&”进行调用;如果先定义子程序后调用,可以省略“&”符号。$n=0;while($n=4){&marine;}submarine{$n++;printHello,sailornumber$n!\n;}print\n;$n=0;while($n=4){marine;}子程序的返回值缺省情况下,子程序中最后一个被执行的语句的值将作为返回值。subsum_of_fred_and_barney{print\$fredis$fred.\n;print\$barneyis$barney.\n;$fred+$barney;#print$fred+$barney;#返回1,非预期结果}$fred=3;$barney=4;$wilma=&sum_of_fred_and_barney;print\$wilmais$wilma.\n;$betty=3*&sum_of_fred_and_barney;print\$bettyis$betty.\n;注意:子程序返回值不是该程序的最后一条表达式sublarger_of_fred_or_barney{if($fred$barney){$fred;}else{$barney;}}$fred=5;$barney=3;$larger=&larger_of_fred_or_barney;print$larger\n;使用warningsusewarnings;sublarger_of_fred_or_barney{if($fred$barney){$fred;}else{$barney;}}$fred=5;$bareny=3;#问题在这$larger=&larger_of_fred_or_barney;print$larger\n;使用strict在上述代码开始处加上usestrict会发生什么?解决办法:在所有变量前添加my关键字参数传递如果函数调用后面跟着一个列表,在函数调用期间该列表将被自动分配给以@_命名的特殊变量。函数可以访问该变量,从而确定参数的个数及赋值。$n=&max(10,15);#此子程序有2个参数submax{if($_[0]$_[1]){#和默认变量$_无关$_[0];}else{$_[1];}print$n;注意:如果传入的参数没有用到,那么会被忽略。如果传入的参数不足,则@_中剩余的变量定义为undef。@_是子程序的一个私有变量;如果有一个全局变量@_,它将在此子程序调用前存储起来,当子程序调用完成后,其早期的值会被重新赋还给@_。练习:以命令行方式输入两个正整数,通过调用子程序完成两者间的加减乘除运算并打印。&operation($ARGV[0],$ARGV[1]);suboperation{$a1=$_[0]+$_[1];$a2=$_[0]-$_[1];$a3=$_[0]*$_[1];$a4=$_[0]/$_[1];print$a1\n;print$a2\n;print$a3\n;print$a4\n;}子程序中的私有变量默认情况下,Perl中所有变量都是全局的,这些变量可以在程序的任意部分使用。可以使用my创建私有变量:submax{my($m,$n);($m,$n)=@_;#my($m,$n)=@_;if($m$n){$m;}else{$n;}}$larger=max(3,5);print$larger;high-watermark算法寻找最大元素$maximum=&max(3,5,10,4,6);submax{my($max_so_far)=shift@_;print$max_so_far\t;print@_\n;foreach(@_){if($_$max_so_far){$max_so_far=$_;}print$_\t$max_so_far\n;}$max_so_far;}print$maximum;local局部变量local和my都只在子程序里有效,出去就失效;如果有与外界同名的变量,两者在从子程序退出后都不影响外界同名变量。subadd_all{local$sum;$sum=0;foreach$_(@_){$sum+=$_;}$sum;}$sum=88;print$sum\n;$a=&add_all(3,4,5);print$sum\n;my和local的区别local变量可以继续在block中调用的子程序中存在,而my则不能。return返回操作return用于从子程序中返回所需要的值,当程序执行到return语句时,立即返回这个值,不再执行下面的语句。my@names=qw/fredbarneybettydino/;my$result=&which_element_is(dino,@names);subwhich_element_is{my($what,@array)=@_;foreach(0..$#array){if($whateq$array[$_]){return$_;}}-1;}$result+=1;printthenumberis:$result;#thenumberis4非标量返回值子程序不仅可以返回标量,还可以返回列表。sublist_from_fred_to_barney{if($fred$barney){$fred..$banrey;}else{reverse$barney..$fred;}}$fred=11;$barney=6;@c=&list_from_fred_to_barney;print@c;#打印出11109876传递数组简单变量和数组变量可以同时传递。例如:&twoargs(47,@mylist);&twoargs(@mylist);#@mylist的第一个元素赋给$scalarsubtwoargs{my($scalar,@list)=@_;……}参数为多个数组时,子程序只将它赋给一个数组变量。例如:&twolist(@mylist1,@mylist2);subtwolists{my(@list1,@list2)=@_;#全部赋给@list1……}错误示例my@names=qw/fredbarneybettydino/;my$result=&which_element_is(@names,dino);subwhich_element_is{my(@array,$what)=@_;print\$what:$what\n;print\@array:@array\n;foreach(0..$#array){if($whateq$array[$_]){return$_;}}-1;}$result+=1;printthenumberis:$result;如何正确传递数组my@names=qw/fredbarneybettydino/;my$result=&which_element_is(\@names,dino);subwhich_element_is{my($array,$what)=@_;print\$what:$what\n;print\$array:@$array\n;foreach(0..$#$array){if($whateq@$array[$_]){return$_;}}-1;}$result+=1;printthenumberis:$result;#!/usr/bin/perlusewarnings;@fruit=qw(appleorangebanana);@veggies=qw(carrotcabbageturnip);getarrays(\@fruit,\@veggies);#通过引用进行传递subgetarrays{my($fruit_ref,$veg_ref)=@_;#注意接收变量的类型printFruit:@$fruit_ref\n;printVeggies:@$veg_ref\n;(@$fruit_ref[0],@$fruit_ref[1])=(@$fruit_ref[1],@$fruit_ref[0]);(@$veg_ref[1],@$veg_ref[2])=(@$veg_ref[2],@$veg_ref[1]);}printAfterorderchange:\n;printFruit:@fruit\n;printVeggies:@veggies\n;如何正确传递多维数组递归函数Perl中函数可以互相调用,其调用方法与上述相同,当调用该函数本身时,即成了递归函数。递归函数有两个条件:1、除了不被函数改变的变量外,所有的变量必须是局部的;2、该函数要含有停止调用本身的代码。$fv=&fact(10);printThefactorialof10is$fv\n;subfact{my$val=$_[0];if($val1){$fv=$val*fact($val-1);}else{$fv=1;}}#Thefactorialof10is3628800预定义的子程序PERL5预定义了三个子程序,分别在特定的时间执行,包括:BEGIN子程序在程序启动时被调用;END子程序在程序结束时被调用;AUTOLOAD子程序在找不到某个子程序时被调用。也可以自己定义它们,例如:BEGIN{print(Hi!WelcometoPerl!/n);}AUTOLOAD{print(subroutine$AUTOLOADnotfound/n);print(argumentspassed:@_/n);}
本文标题:perl第5章
链接地址:https://www.777doc.com/doc-1889206 .html