zoukankan      html  css  js  c++  java
  • 第一章 数据引用与匿名存储

    数据引用与匿名存储:
    
    1.不必使用变量名就能够动态地位数据分配存储空间,我们称之为匿名数据结构
    
    2.可以指向任何数据结构,无论它是静态分配还是动态分配的
    
    Perl的引用同样可以指向常规数据类型(如标量变量,数组和散列表)和其他类型的实体。
    
    比如下面这行代码:
    
    [root@node01 1]# cat a1.pl 
    use Data::Dumper;
    $line[19]="hello";
    
    print @line;
    print "
    ";
    print Dumper(@line);
    print "
    ";
    [root@node01 1]# perl a1.pl 
    hello
    $VAR1 = undef;
    $VAR2 = undef;
    $VAR3 = undef;
    $VAR4 = undef;
    $VAR5 = undef;
    $VAR6 = undef;
    $VAR7 = undef;
    $VAR8 = undef;
    $VAR9 = undef;
    $VAR10 = undef;
    $VAR11 = undef;
    $VAR12 = undef;
    $VAR13 = undef;
    $VAR14 = undef;
    $VAR15 = undef;
    $VAR16 = undef;
    $VAR17 = undef;
    $VAR18 = undef;
    $VAR19 = undef;
    $VAR20 = 'hello';
    
    
    它创建了20个元素的数组,然后将最后一个元素复制为一个字符串。同样的工作在C语言中要花费很多行的diamante
    
    Perl将确保一块数据当且仅当没有任何引用的情况下才被释放(这就确保了内存泄露不会发生)
    
    [root@node01 1]# cat a2.pl 
    $a="mam mia";
    @array=(10,20);
    %hash=("laurel"=>"hardy","nick"=>"nora");
    
    ##现在创建对它们的引用
    
    $ra=$a;
    $rarray=@array;
    $rhash=\%hash;
    
    print $ra;
    print "
    ";
    
    print $rarray;
    print "
    ";
    
    
    print $rhash;
    print "
    ";
    [root@node01 1]# perl a2.pl 
    SCALAR(0x1d72be8)
    ARRAY(0x1d72c30)
    HASH(0x1d72cc0)
    
    引用本身就是一种标量变量:
    
    
    间接访问(dereference)的意思就是取得引用所指的变量的值:
    
    
    在C语言中,如果p是一个指针,那么*p就表示p所指向的值。
    
    
    在Perl中如果$r是一个引用,那么$$r,@$r或%$r分别$r所引用的数据类型
    
    (标量变量,数组,散列表)获取的相应的值。
    
    [root@node01 1]# cat a3.pl 
    $a="mam mia";
    @array=(10,20);
    
    ##现在创建对它们的引用
    
    $ra=$a;
    $rarray=@array;
    
    print %$rarray;
    [root@node01 1]# perl a3.pl 
    Not a HASH reference at a3.pl line 9.
    [root@node01 1]# 
    
    对标量变量的引用:
    
    
    以下是包含有标量变量的表达式:
    
    
    对数组的引用:
    
    简明的箭头记号:
    
    [root@node01 1]# cat a5.pl 
    my @array=(1,4,7,2,5,8);
    
    $rarray=@array;
    print $$rarray[2];
    print "
    ";
    [root@node01 1]# perl a5.pl 
    7
    
    [root@node01 1]# cat a5.pl 
    my @array=(1,4,7,2,5,8);
    
    $rarray=@array;
    print $rarray->[2];
    print "
    ";
    [root@node01 1]# perl a5.pl 
    7
    
    与数组类似,你可以通过使用->{}记号来存取散列表中的数据元素;
    
    [root@node01 1]# cat a6.pl 
    my %hash=("a"=>"a11","b"=>"b11");
    my $rhash=\%hash;
    print $rhash->{"a"};
    print "
    ";
    [root@node01 1]# perl a6.pl 
    a11
    
    不存在自动间接访问:
    
    [root@node01 1]# perl a7.pl 
    push on reference is experimental at a7.pl line 3.
    [root@node01 1]# cat a7.pl 
    my @array=('aa','bb','cc');
    $rarray=@array;
    push ($rarray,1,2,3,);
    [root@node01 1]# perl a7.pl 
    push on reference is experimental at a7.pl line 3.
    
    
    [root@node01 1]# cat a7.pl 
    my @array=('aa','bb','cc');
    print "@array=@array
    ";
    $rarray=@array;
    push (@$rarray,1,2,3,);
    print "@array=@array
    ";
    [root@node01 1]# perl a7.pl 
    @array=aa bb cc
    @array=aa bb cc 1 2 3
    
    
    
    向子例程传递数组和散列表:
    
    当你要向子例程中传递一个以上的数组或散列表时,Perl将会把它们合并到@_数据中供子例程使用。
    
    
    [root@node01 1]# cat a8.pl 
    sub fun1 {
      my (@arr1,@arr2)=@_;
      print "@arr1 =@arr1
    ";
      print "@arr2 =@arr2
    ";
    
    };
    
    
    fun1((1,2,3),(4,5,6));
      
    [root@node01 1]# perl a8.pl 
    @arr1 =1 2 3 4 5 6
    @arr2 =
    
    Perl 将会把它们合并到@_数组中供子例程使用。
    
    
    唯一避免合并的方法就是传输输入数组或散列表的引用。
    
    [root@node01 1]# cat a9.pl 
    @array1=(1,2,3);
    @array2=(4,5,6,7);
    AddArrays (@array1,@array2);  #以引用方式传递数组
    print "@array1=@array1
    ";
    print "@array2=@array2
    ";
    
    sub AddArrays {
       my ($rarray1,$rarray2) =@_;
       $len2=@$rarray2;#array2的长度
       for ($i=0;$i<$len2;$i++){
        $rarray1->[$i] += $rarray2->[$i];
        print "$rarray1->[$i]=$rarray1->[$i]
    ";
    };
    };
    [root@node01 1]# perl a9.pl 
    $rarray1->[0]=5
    $rarray1->[1]=7
    $rarray1->[2]=9
    $rarray1->[3]=7
    @array1=5 7 9 7
    @array2=4 5 6 7
    [root@node01 1]# 
    
    
    匿名存储的引用:
    
    到目前为止,我们学习创建了对已存在变量的引用,现在我们要学习对"匿名"数据结构的引用,
    
    也就是那些没有同变量名关联的值。
    
    创建匿名数组,需要使用方括号而不是圆括号,如:
    
    
    $ra=[]; #创建一个空的匿名数组,并返回对它的引用
    
    $ra=[1,"hello"];#创建一个经过初始化的匿名数组,并返回对它的引用
    
    [root@node01 1]# cat a10.pl 
    use Data::Dumper;
    $ra=[];
    $ra=[1,"hello"];
    print Dumper($ra);
    print "
    ";
    print @$ra;
    
    
    
    [root@node01 1]# perl a10.pl 
    $VAR1 = [
              1,
              'hello'
            ];
    
    
    
    多重引用的间接访问:
    
    
    嵌套数据结构:
    
    John[root@node01 1]# cat a11.pl 
    %sue =(
       'name'=>'Sue',
       'age'=>'45');
    
    %john=(
         'name'=>'John',
         'age'=>'20'
       );
    
    %peggy=(
        'name'=>'Peggy',
        'age'=>'16');
    
    @children=(\%john,\%peggy);
    
    $sue{'children'}=@children;
    
    print %sue;
    print "
    ";
    print $sue{'children'};
    print "
    ";
    print @{$sue{'children'}};
    print "
    ";
    foreach (@{$sue{'children'}}){
    print %{$_};
    print "
    ";
    };
    
    print  $sue{'children'}->[0]->{'name'};
    [root@node01 1]# perl a11.pl 
    nameSuechildrenARRAY(0xafa168)age45
    ARRAY(0xafa168)
    HASH(0xaedc90)HASH(0xaedd38)
    age20nameJohn
    age16namePeggy
    John[root@node01 1]# 
    
    
    
    
    隐含的创建复杂的数据结构:
    
    最后的缩写:省去两个下标间的箭头:
    
    [root@node01 1]# cat a11.pl 
    %sue =(
       'name'=>'Sue',
       'age'=>'45');
    
    %john=(
         'name'=>'John',
         'age'=>'20'
       );
    
    %peggy=(
        'name'=>'Peggy',
        'age'=>'16');
    
    @children=(\%john,\%peggy);
    
    $sue{'children'}=@children;
    
    print %sue;
    print "
    ";
    print $sue{'children'};
    print "
    ";
    print @{$sue{'children'}};
    print "
    ";
    foreach (@{$sue{'children'}}){
    print %{$_};
    print "
    ";
    };
    
    print  $sue{'children'}->[0]->{'name'};
    print "
    ";
    print  $sue{'children'}[0]{'name'};
    print "
    ";
    [root@node01 1]# perl a11.pl 
    age45childrenARRAY(0x1d9a1a8)nameSue
    ARRAY(0x1d9a1a8)
    HASH(0x1d8dc90)HASH(0x1d8dd38)
    nameJohnage20
    age16namePeggy
    John
    John
    
    谈到程序员的效率,让我们谈论一个节省键盘敲击次数的技巧。
    
    在两个下标之间(也只有在下标之间)你可以省去箭头符号"->"
    
    
    你会看到即便是如此简单的例子,也更多的得益于匿名的数组和散列表,
    
    而不是有名的数组和散列表。
    
    [root@node01 1]# cat a12.pl 
    %sue = (
        'name' =>'Sue',
        'age'=>'45',
        'children'=>[
                      {
         'name'=>'John',
         'age'=>'20'
         },
         {
           'name' => 'Peggy',
           'age'=>'16'
         }
         ]
    );
     
     
    print %sue;
    print "
    ";   
    [root@node01 1]# perl a12.pl 
    age45childrenARRAY(0x124c540)nameSue
    
    这段代码只有一个有名变量,子属性是一个指向匿名数组的引用,而数组的元素则又包含了指向
    
    带有孩子详信息的匿名散列表。
    
    [root@node01 1]# cat a12.pl 
    %sue = (
        'name' =>'Sue',
        'age'=>'45',
        'children'=>[
                      {
         'name'=>'John',
         'age'=>'20'
         },
         {
           'name' => 'Peggy',
           'age'=>'16'
         }
         ]
    );
     
     
    print %sue;
    print "
    ";   
    print $sue{children}->[1]->{age};
    [root@node01 1]# perl a12.pl 
    age45childrenARRAY(0x159c540)nameSue
    16[root@node01 1]# 
    
    
    引用的查询:
    
    ref 函数被用来查询标量变量是否包含一个引用,是的话,再判定所指向的是什么数据的类型
    
    [root@node01 1]# cat a13.pl 
    my $a="123";
    
    print ref($a);
    print "
    ";
    
    print "-------------
    ";
    my $ra=$a;
    
    print ref($ra);
    print "
    ";
    [root@node01 1]# perl a13.pl 
    
    -------------
    SCAL
    
    
    符号引用:
    


    
                                        
    
  • 相关阅读:
    3.1C#中的命名空间
    2章总结
    2.4冒泡排序
    2.3 C#中的数组
    2.2二重循环
    2.1c#中的循环语句
    1章总结
    docker内外数据拷贝
    搭建docker环境
    centos7 部署Apache的httpd服务器
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13349768.html
Copyright © 2011-2022 走看看