1. 程式人生 > >【perl】函式的引數變數和返回值

【perl】函式的引數變數和返回值

函式返回值

在Perl中,return語句可以返回一個標量值或者一個列表,這個標量值可以是一個變數,或者一個表示式的最後求值,如:return 1;<===>return(1);    return $a+$b; <===>return($a+$b);
一個Perl函式的返回值,並不止一個,有時會有多個值需要返回,這時就要用到列表,這個列表可以包含多個變數值。

 

返回單一變數

  
  subget_value()  
  {  
    my $var;  
    $var=1;  
    return($var);  
  }  


 my $result;  
 $result = get_value();  
 print "\$result = $result \n";  


返回多個標量

  subget_value()  {  
     my($var_a,$var_b);  
     $var_a=1;  
     $var_b=2;  
     return($var_a,$var_b);  
  }  

 my ($result_a,$result_b);  

 ($result_a,$result_b) = get_value(); 

返回多個陣列

 sub get_value()  
 {  
   my(@$var_a,@var_b);  
   @var_a=(1,2);  
   @var_b=(30,40);  
   return(\@var_a,\@var_b);  
  }  


 my (@result_a,@result_b);  
 my ($result_a_ref,$result_b_ref);  
 ($result_a_ref,$result_b_ref)=get_value();  
 #here need to encode the reference  
 @
[email protected]
$result_a_ref; @[email protected]$result_b_ref; print"\@[email protected]_a\n\@[email protected]_b\n"; #######print resultis: @result_a=1,2 @result_b=30,40

引數中傳遞陣列

 

sub getarrays{

  my(@a,@b) = @_; #  @_ 是預設的包含本函式所有引數
  ...
}

@fruit = qw(apples oranges banana);

@veggies = qw(carrot cabbage turnip);

getarrays(@fruit, @veggies);

預期 @fruit 會賦值給@a,@veggies賦值給@b,其實不然

在呼叫getarrays(@fruit, @veggies)時,其把引數@fruit 和 @veggies壓縮到單個數組@_中。

這樣在getarrays函式內部,就會把@_賦值給@a,即@fruit和@veggies都賦值給@a.

 

傳遞引數引用可以很好的解決這個問題。即我們沒有必要傳遞整個陣列,只要傳遞相關陣列的引用就可以了。

引用一律宣告為標量型別(即$開頭的命名變數),使用\運算子取引用 
對引用變數的修改等同於對引用指向實際資料的修改 
標量變數引用:my $scalar_r = \$scalar; 
列表的引用:my $array_r = \@array; 
雜湊的引用:my $hash_r = \%hash; 

1、一般的標量Perl引用

  

     sub add{  my($a,$b)[email protected]_;  $$a++;  $$b++;  } 

     $a=1;  $b=2; 
     add(\$a,\$b);  print "$a,$b\n";       # 輸出:2,3。

 
     說明:取變數的Perl引用可以用“\”符號,解Perl引用用“$”符號。

2、陣列的Perl引用

陣列的Perl引用和標量的Perl引用一樣,在陣列名前面加“\”,只是在解Perl引用的時候,使用@符號。如: 
     @abc=(1,2,3); 
     $ref = \@abc; 
     print “@$ref \n”;  #輸出1,2,3。 
     print “@$ref[0] \n”;  #輸出1。 
 

3、對雜湊表的Perl引用

和陣列類似,但是當解Perl引用時要使用$符號,如: 
    %hash=(abc=>123, def=>456); 
    $ref=\%hash; 
    print "%$ref \n";  # 輸出:%HASH(0x83179b4) 
    print "$$ref{abc}\n"; # 輸出:123

引用的賦值

$aref2 = $aref1; 將使得$aref2和$aref1指向同一個陣列,如果想將$aref1指向的陣列拷貝一份給$aref2的話,使用下面的方法,[]裡面對陣列進行解引用,而[]以解引用後的陣列為內容生成了一個新的匿名陣列,又賦值給$aref2。

$aref2 = [@{$aref1}]; 

注意:不能使用下面的形式,外層的[]是不可缺少的。由於=左邊是標量,所以右邊的陣列會被解釋為標量環境,得到的是陣列元素個數,而不是元素本身。但是如果加上[]就可以了,這樣perl知道這是一個匿名陣列的賦值。

$aref2 = @{$aref1};

判斷一個變數是否是引用

my $aref1 = [1, 2, 0] ;

print ref $aref1, "\n" ; #輸出 ARRAY

if (ref $aref1) {
    print "true\n" ; #輸出 true
}

判斷兩個引用是否指向同一個目標

my $aref1 = [1, 2, 0] ;
my $aref2 = $aref1 ;
print $aref1, "\n" ;
print $aref2, "\n" ;

if ($aref1 eq $aref2) {
    print "reference equal\n" ;
}
if($aref1 == $aref2) {
    print "reference equal\n" ;
}

 

 

例1:

sub getarrays{

    my($fruit_ref,$veg_ref) = @_;
    ...
}


@fruit = qw(apples oranges banana);

@veggies = qw(carrot cabbage turnip);

getarrays(\@fruit, \@veggies);

例2:

sub func
{
        my($a,$b,$c) = @_;    # 這裡$b,$c接收到的是陣列的引用
        
        print "$a\n";
        my $count = 0;
        
        while($count < @$b)
        {
                print "$b->[$count]\n";
                $count++;
        }
        $count = 0;
        while($count < @$c)
        {
                print "$c->[$count]\n";
                $count++;
        }
}

my @arry1 = ("fff", "rrr", "www");
my @arry2 = ("ttt", "hhh", "ccc");

func("qqq", \@arry1, \@arry2); #  這裡傳入陣列的引用

二維陣列
@a = {
            (a,b,c,d,e)
            (f,g,h,i,j,k)
            (l,m,n,o,p)
            (q,r,s,t,u)
            (v,w,x,y,z)
}

從上述二維陣列的每一行的陣列中選出一個元素,列舉出所有的組合方式.
例如可行組合(a,f,l,q,v),(b,h,o,s,z)等。

my @A = ( [ 1 .. 4 ], [ 'A' .. 'C' ], [ 'a', 'b' ], [ 10 .. 13 ] );

sub Combine {
    my @R = @{ +shift };# @R = [1..4]
    for my $e (@_) {
        @R = map { my $r = $_; map "$r $_", @$e } @R;#其中@$e是參考引用
    }
    return @R;
}
my @w = Combine @A;

foreach my $t (@w){
  print $t."\n";
}
#say for @w

ref:link1    link2