Perl学习之四:子程序

一、子程序含义及命名规则

  • perl中的子程序即是用户自己定义的函数
  • 子程序的名称也是perl的标识符,即由字母、数字、下划线组成,但不能由数字开头

二、定义子程序

  • 子程序由关键字sub、子程序名及花括号内的代码块组成
  • 子程序的定义是全局的
  • 不需对子程序事先声明
  • 可在任意位置定义
  • 若存在重名子程序,后面的子程序将覆盖前面的

三、调用子程序

  • 可在任意表达式中使用“&子程序名”来调用子程序
  • 若子程序的调用是在子程序声明的后面,且子程序名不跟内置函数重名,则可在调用子程序时省略&号

    例:

    &printNum;      # 打印:number 1

    printNum;        # 打印:number 2,此处省略了&号

    &printNum;      # 打印:number 3

四、子程序返回值

  • 每个子程序都有一个返回值
  • 返回值是子程序中最后执行的表达式

    例1:返回值为标量

    sub printNum {
        print "The return value is";    

        $x + $y;                             # $x + $y是子程序的返回值
    }
    $x = 2;      
    $y = 3; 
    $return = &printNum;
    print " $return";
 

    运行结果:

    The return value is 5

     例2:

    sub printNum {
        $x = 3;                                          # $x + $y不是子程序的返回值

        print "The return value is not $x!/n";  # 最后执行的表达式不是$x,而是print语句,打印成功返回真值(一般是1),若失败返回假值0   

    }
    $return = &printNum;
    print "The return value is $return.";

    运行结果:

    The return value is not 3!

    The return value is 1.

     例3:返回值为非标量

 

      sub reList {
        if ($a < $b) {

            $a..$b;                # 从$a到$b的列表 

        } else {

            reverse $a..$b;     # 从$b到$a的列表,因为范围操作符“..”只能递增不能递减,所以此处用reverse倒序

        }  

    }
    $a = 10;      
    $b = 5;  
    @result = &reList;     
  # @result的值为(10, 9, 8, 7, 6, 5)

 

四、子程序参数

  • 参数传递:只需在子程序调用后面加上括号括起来的列表表达时即可
  • perl会自动将参数列表存入特殊的数组变量@_,该变量在子程序执行期间有效
  • @_的第1个参数为$_[0],第二个参数为$_[1],依此类推

    例:输出子程序的最大参数

     sub max {

         if ($_[0] > $_[1]) {

              $_[0];      

         } else {

              $_[1];         

         }

    } 

    $max0 = &max();                  # 空参数的子程序调用,&max()相当于&max

    $max1 = &max(5);                # 包含一个参数的子程序调用,$_[1]超出数组边界,得到undef

    $max2 = &max(5, 10);           # 包含两个参数的子程序调用

    $max3 = &max(5, 10, 15);     # 包含三个参数的子程序调用,最后一个参数未使用,被忽略

    print "The biggest parameter is $max0./n";

    print "The biggest parameter is $max1./n";

    print "The biggest parameter is $max2./n";

    print "The biggest parameter is $max3./n";

    运行结果:

    The biggest parameter is .

    The biggest parameter is 5.

    The biggest parameter is 10.

    The biggest parameter is 10.

     例:限制子程序参数个数

     sub max {

         if (@_ != 2) {   # 这里直接用数组名称来取得数组元素个数,即子程序的参数个数

             print "WARNING:$max should get exactly two arguments!/n";

         }

         # 其余代码略

     }

五、私有变量

  • 运用my操作符来创建私有变量

        例:

        my($a);             # 声明单个私有变量   

       my $a;              # 声明单个私有变量   

  • 私有变量作用范围在语句块内,包括子程序、foreach、if等所有语句块

       my($a, $b);       # 声明多个私有变量   

       my $a, $b;        # 声明了一个似有变量$a和一个全局变量$b

       my @a;            # 声明一个私有数组变量

  • 私有变量赋值

        例:

        my($a) = 3;                 # 相当于my($a); $a = 3;两句

        my($a, $b) = (3, 4);      # 相当于my ($a, $b); ($a, $b) = (3, 4);

       my $a, $b =  (3, 4);      # 声明一个私有变量$a和一个全局变量$b,并赋值 

       my @a = qw/a b c /;     # 声明一个私有数组变量,并赋值   

       my($a, $b, $c) = @a ;   # 将@a中的元素分别赋值给三个私有变量 

       my($a) = @a ;             # 列表上下文:将@a中的第一个元素赋值给$a,$a值为a

       my $a = @a ;               # 标量上下文:将@a中的元素个数赋给$a,$a值为3

  • 私有变量作用范围在语句块内,包括子程序、foreach、if等所有语句块

     例1:求数组最大值

     $maximum = &getMax(3,5,10,4,6);
     print "The maximum is $maximum.";

 

     sub getMax {
         my($max) = shift @_;   #删除数组中第一个值并放入$max中
         foreach (@_) {             #遍历@_中其他元素,foreach中省略了控制变量,默认$_为控制变量
             if ($_ > $max) {      #循环中的当前元素$_大于$max?
                 $max = $_;    
             }
         }
         $max;                        #返回数组中的最大值
     }

     运行结果:

      The maximum is 10.

     例2:

      foreach (1..10) {
         my($square) = $_ * $_;
         print "$_ squared is $square./n";
     }

     运行结果:

      1 squared is 1.
     2 squared is 4.
     3 squared is 9.
     4 squared is 16.
     5 squared is 25.
     6 squared is 36.
     7 squared is 49.
     8 squared is 64.
     9 squared is 81.
     10 squared is 100.

  • 持久化私有变量state(在Perl5.10中才有),可在子程序的多次调用间保留变量的值,并将变量的作用域局限于子程序中

    例:

    use 5.010;
    &running_sum(5, 6);
    &running_sum(1..3);
    &running_sum(4);

    sub running_sum {
        state $sum = 0;
        state @numbers;

        foreach my $number (@_) {
           push @numbers, $number;
           $sum += $number;
        }
        say "The sum of (@numbers) is $sum";
     }

     运行结果:   

      The sum of (5 6) is 11

     The sum of (5 6 1 2 3) is 17

     The sum of (5 6 1 2 3 4) is 21

  • 不能在列表上下文中初始化数组和哈希类型的state变量(在Perl5.10中才有

    例:

    state @array = qw/a b c/;    # 这种写法是错误的

六、return操作符

  • return用于从子程序中返回某个值
  • 只有返回没有发生在最后一行代码时才需要使用return
  • 只单独写一个return时,在标量上下文中返回值为undef,列表上下文中返回值为空列表

     例:找出字符串在数组中的下标值

     my @names = qw/a b c d e/;

    my $result = &getIndex("c", @names);

   

     sub getIndex {

         my($what , @array) = @_;

         foreach (0..$#array) {                # 数组中所有元素的下标

             if ($what eq $array[$_]) {       # 字符串相等比较用eq

                 return $_;                         # 一找到就返回

            }

         }

         -1;      # 没有找到符合条件的元素返回-1,return在此处可有可无,省略此句则返回值为undef

     }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值