Username: Password:

perl实例分析教程之十五
来源:linux宝库作者:linux宝库 发布时间:2007-09-30 00:00:00


  Perl中的“引用”

  一、引用简介

  二、使用引用

  三、使用反斜线()操作符

  四、引用和数组

  五、多维数组

  六、子程式的引用

  七、数组和子程式

  八、文档句柄的引用

  一、引用简介

  引用就是指针,能够指向变量、数组、哈希表(也叫关联数组)甚至子程式。Pascal或C程式员应该对引用(即指针)的概念很熟悉,引用就是某值的地址,对其的使用则取决于程式员和语言的规定。在Perl中,能够把引用称为指针,二者是通用的,无差别的。引用在创建复杂数据方面十分有用。

  Perl5中的两种引用类型为硬引用和符号引用。符号引用含有变量的名字,他对运行时创建变量名并定位很有用,基本上,符号引用就象文档名或UNIX系统中的软链接。而硬引用则象文档系统中的硬链接。

  Perl4只允许符号引用,给使用造成一些困难。例如,只允许通过名字对包的符号名哈希表(名为_main{})建立索引。Perl5则允许数据的硬引用,方便多了。

  硬引用跟踪引用的计数,当其数为零时,Perl自动将被引用的项目释放,假如该项目是对象,则析构释放到内存池中。Perl本身就是个面向对象的语言,因为Perl中的任何东西都是对象,包和模块使得对象更易于使用。

  简单变量的硬引用很简单,对于非简单变量的引用,您必须显式地解除引用并告诉其应怎样做,详见《Perl中的面向对象编程》。

  二、使用引用

  本章中,简单变量指像$pointer这样的变量,$pointer仅含一个数据项,其能够为数字、字符串或地址。

  任何简单变量均可保存硬引用。因为数组和哈希表含有多个简单变量,所以能够建立多种组合而成的复杂的数据结构,如数组的数组、哈希表的数组、子程式的哈希表等等。只要您理解其实只是在用简单变量在工作,就应该能够正确的在最复杂的结构中正确地解除引用。

  首先来看一些基本要点。

  假如$pointer的值为一个数组的指针,则通过形式@$pointer来访问数组中的元素。形式@$pointer的意义为“取出$pointer中的地址值当作数组使用”。类似的,%$pointer为指向哈希表中第一个元素的引用。

  有多种构建引用的方法,几乎能够对任何数据建立引用,如数组、简单变量、子程式、文档句柄,连同--C程式员会感兴趣的--引用。Perl使您有能力写出把自己都搞糊涂的极其复杂的代码。:)

  下面看看Perl中创建和使用引用的方法。

  三、使用反斜线()操作符

  反斜线操作符和C语言中传递地址的操作符&功能类似。一般是用创建变量又一个新的引用。下面为创建简单变量的引用的例子:

  $variavle = 22;

  $pointer = $variable;

  $ice = "jello";

  $iceprt = $ice;

  引用$pointer指向存有$variable值的位置,引用$iceptr指向"jello"。即使最初的引用$variable销毁了,仍然能够通过$pointer访问该值,这是个硬引用,所以必须同时销毁$pointer和$variable以便该空间释放到内存池中。

  在上面的例子中,引用变量$pointer存的是$variable的地址,而不是值本身,要获得值,形式为两个$符号,如下:

  #!/usr/bin/perl

  $value = 10;

  $pointer = $value;

  printf "n Pointer Address $pointer of $value n";

  printf "n What Pointer *($pointer) points to $$pointern";

  结果输出如下:

  Pointer Address SCALAR(0x806c520) of 10

  What Pointer *(SCALAR(0x806c520)) points to 10

  每次运行,输出结果中的地址会有所改变,但能够看到$pointer给出地址,而$$pointer给出$variable的值。

  看一下地址的显示,SCALAR后面一串十六进制,SCALAR说明该地址指向简单变量(即标量),后面的数字是实际存贮值的地址。

  注意:指针就是地址,通过指针能够访问该地址处存贮的数据。假如指针指向了无效的地址,就会得到不正确的数据。通常情况下,Perl会返回NULL值,但不该依赖于此,一定要在程式中把任何的指针正确地初始化,指向有效的数据项。

  四、引用和数组

  关于Perl语言应该记住的最重要的一点可能是:Perl中的数组和哈希表始终是一维的。因此,数组和哈希表只保存标量值,不直接存贮数组或其他的复杂数据结构。数组的成员要么是数(或字符串)要么是引用。

  对数组和哈希表能够象对简单变量相同使用反斜线操作符,数组的引用如下:

  1 #!/usr/bin/perl

  2 #

  3 # Using Array references

  4 #

  5 $pointer = @ARGV;

  6 printf "n Pointer Address of ARGV = $pointern";

  7 $i = scalar(@$pointer);

  8 printf "n Number of arguments : $i n";

  9 $i = 0;

  10 foreach (@$pointer) {

  11 printf "$i : $$pointer[$i++]; n";

  12 }

  运行结果如下:

  $ test 1 2 3 4

  Pointer Address of ARGV = ARRAY(0x806c378)

  Number of arguments : 4

  0 : 1;

  1 : 2;

  2 : 3;

  3 : 4;

  第5行将引用$pointer指向数组@ARGV,第6行输出ARGV的地址。$pointer返回数组第一个元素的地址,这和C语言中的数组指针是类似的。第7行调用函数scalar()获得数组的元素个数,该参数亦可为@ARGV,但用指针则必须用@$pointer的形式指定其类型为数组,$ pointer给出地址,@符号说明传递的地址为数组的第一个元素的地址。第10行和第7行类似,第11行用形式$$pointer[$i]列出任何元素。

  对关联数组使用反斜线操作符的方法是相同的--把任何关联数组名换成引用$poniter。注意数组和简单变量(标量)的引用显示时均带有类型--ARRAY和SCALAR,哈希表(关联数组)和函数也相同,分别为HASH和CODE。下面是哈希表的引用的例子。

  #!/usr/bin/perl

  1 #

  2 # Using Associative Array references

  3 #

  4 %month = (

  5 ’01’, ’Jan’,

  6 ’02’, ’Feb’,

  7 ’03’, ’Mar’,

  8 ’04’, ’Apr’,

  9 ’05’, ’May’,

  10 ’06’, ’Jun’,

  11 ’07’, ’Jul’,

  12 ’08’, ’Aug’,

  13 ’09’, ’Sep’,

  14 ’10’, ’Oct’,

  15 ’11’, ’Nov’,

  16 ’12’, ’Dec’,

  17 );

  18

  19 $pointer = %month;

  20

  21 printf "n Address of hash = $pointern ";

  22

  23 #

  24 # The following lines would be used to print out the

  25 # contents of the associative array if %month was used.

  26 #

  27 # foreach $i (sort keys %month) {

  28 # printf "n $i $$pointer{$i} ";

  29 # }

  30

  31 #

  32 # The reference to the associative array via $pointer

  33 #

  34 foreach $i (sort keys %$pointer) {

  35 printf "$i is $$pointer{$i} n";

  36 }

  结果输出如下:

  $ mth

  Address of hash = HASH(0x806c52c)

  01 is Jan

  02 is Feb

  03 is Mar

  04 is Apr

  05 is May

  06 is Jun

  07 is Jul

  08 is Aug

  09 is Sep

  10 is Oct

  11 is Nov

  12 is Dec

  和数组类似,通过引用访问哈希表的元素形式为$$pointer{$index},当然,$index是哈希表的键值,而不但是数字。更有几种访问形式,此外,构建哈希表还能够用=>操作符,可读性更好些。下面再看一个例子:

  1 #!/usr/bin/perl

  2 #

  3 # Using Array references

  4 #

  5 %weekday = (

  6 ’01’ => ’Mon’,

  7 ’02’ => ’Tue’,

  8 ’03’ => ’Wed’,

  9 ’04’ => ’Thu’,

  10 ’05’ => ’Fri’,

  11 ’06’ => ’Sat’,

  12 ’07’ => ’Sun’,

  13 );

  14 $pointer = %weekday;

  15 $i = ’05’;

  16 printf "n ================== start test ================= n";

  17 #

  18 # These next two lines should show an output

  19 #

  20 printf ’$$pointer{$i} is ’;

  21 printf "$$pointer{$i} n";

  22 printf ’${$pointer}{$i} is ’;

  23 printf "${$pointer}{$i} n";

  24 printf ’$pointer->{$i} is ’;

  25

  26 printf "$pointer->{$i}n";

  27 #

  28 # These next two lines should not show anything 29 #

  30 printf ’${$pointer{$i}} is ’;

  31 printf "${$pointer{$i}} n";

  32 printf ’${$pointer->{$i}} is ’;

  33 printf "${$pointer->{$i}}";

  34 printf "n ================== end of test ================= n";

  35

  结果输出如下:

  ================== start test =================

  $$pointer{$i} is Fri

  ${$pointer}{$i} is Fri

  $pointer->{$i} is Fri

  ${$pointer{$i}} is

  ${$pointer->{$i}} is

  ================== end of test =================

  能够看到,前三种形式的输出显示了预期的结果,而后两种则没有。当您不清楚是否正确时,就输出结果看看。在Perl中,有不明确的代码就用print语句输出来实验一下,这能使您清楚Perl是怎样解释您的代码的。

喜欢本文,那就收藏到:

    Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
相关评论  我也要评论
还没有关于此文章的相关评论!
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
  • 导航
    赞助商
    文章类别
    订阅