Chinaunix首页 | 论坛 | 博客
  • 博客访问: 547494
  • 博文数量: 201
  • 博客积分: 7734
  • 博客等级: 少将
  • 技术积分: 1994
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-09 19:18
文章分类

全部博文(201)

文章存档

2011年(28)

2010年(173)

分类:

2010-08-16 09:34:03

第三章:列表与数组

如果说Perl的标量代表的是单数(singular),那么正如第二章开头所讲的,在Perl里代表复数(plural)

的就是列表和数组。


列表(list)指的是标量的有序集合,而数组(array)则是存储列表的变量。在Perl里,这两个术语常常混

用。不过更精确地说,列表指的是数据,而数组指的是变量。列表的值不一定要放在数组里,但每一个

数组变量都一定包含一个列表(即使该列表可能是空的)

数组或列表的每个元素(element)都是单独的标量,拥有独立的标量值。这些值是有序的。也就是说,从

起始元素到终止元素的先后次序是固定的。数组或列表中的每一个元素都有相应的整数作为索引,此数

字从0开始递增,每次加一。所以数组或列表的头一个元素总是第0个元素。

访问数组中的元素:

任何求值能得到数字的表达式都可以用作下标。假如它不是整数,则会自动舍去小数。无论正负:

#!/usr/bin/perl -w
$fred[0] = "yabba";
$fred[1] = "dabba";
$fred[2] = "doo";

============================

print $fred [0];
$fred[2] = "diddley";
$fred[1] .= "whatsis";
$number = 2.71828;
print $fred [ $number - l ]; #结果和print $fred[1]相同。

假如下标超出数组的尾端,则对应的值将会是undev。这点和一般的标量相同,如果从来没有对标量变量

进行过赋值,它的值就是undef。

特殊的数组索引值:

假如你对索引值超过数组尾端的元素进行赋值,数组将会根据需要自动扩大-只要有可用的内存分配给

Perl,数组的长度是没有上限的。如果在扩展过程中需要创建增补元素,那么它们的默认取值为undef。

$rocks[0] = 'bedrock';  #一个元素……
$rocks[1] = 'slate';  #又一个……
$rocks[2] = 'lava';  #再来一个……
$rocks[3] = 'crushed rock'; #再来一个……
$rocks[99] = 'schist';  #现在有95个undef元素

有时候,你会想要找出数组最后一个元素的索引值。对我们正在使用的数组rocks而言,最后一个元素的

索引是$#rocks。但这个数字比数组元素的个数少1,因为还有一个编号为0的元素:

$end = $#rocds;  #99,也就是最后一个元素的索引值
$number_of_rocks = $end + 1; #正确,但后面会看到更好的做法
$rocks[ $#rocks ] = 'hard rock'; #最后一块石头。

也可以用$rock[-1] = 'hard rock';做为最后一个数组的值。

$dead_rock = $rocks [ -100 ]; #得到'bedrock'

列表直接量:

程序中需要引入列表的时候可以写成数组的样子,也就是在圆括号中用逗号隔开的一系列值。这些值构

成了列表中的元素。
(1, 2, 3) #包含1、2、3这三个数字的列表
(1, 2, 3,) #相同的三个数字(末尾的逗号会被忽略)
("fred", 4.5) #两个元素,"fred"和4.6
()  #空列表;零个元素
(1..100) #100个整数构成的列表

最后一行用到了..范围操作符(range operator),它从左边的数字计数到右边,每次加1,以产生一连串

的数字。
(1..5)  #与(1,2,3,4,5)相同
(1.7..5.7) #同上:这两个数字都会被去掉小数部分
(5..1)  #空列表:..仅向上计数
(0,2..6,10,12) #与(0,2,3,4,5,6,10.12)相等
($m..$n) #范围同$m和$n当前的值来决定(0..$#rocks) #上节的rocks数组里的所有索引数字


数组中的元素不必都是常数-它们可以是表达式,在每次用到这些直接量时都会重新计算。

($m,17)  #两个值,$m的当前值,以及17
($m+$o,$p+$q) #两个值
列表可以包含任何标量值,像下面一样的字符串列表
("fred","barney","betty","wilma","dino")

qw简写:

在Perl程序里,经常需要建立简单的单词列表(如同前成的例子)。这时只需要用qw简写,就不必键入许

多索然无味的引号:


qw( fred barney betty wilma)同上,更简洁,也更少的键入。

qw 表示"qoted word" (加上引号的单词)或"quoted by whitespace (用空白圏引)

这个写法的效果和使用单号一样的,所以qw构建的列表,不能像双引号内的字符串一样使用\n或$fred。

空格,制表符,以及换行符也会被抛弃。


qw (fred
 barney betty
wilma dino ) #同上,但空白符字符的用法比较奇怪,
因为
qw算是一种引号,所以不能将注释放在qw列表中。

qw 不紧可以使用()来做为定界符,也可以使用 "!!" , "//" , "##"看起来像是注释  , "{}" , "[]" ,

"<>"

qw! fred barney betty wilma dino !
qw/ fred barney betty wilma dino /

如果需要在被圏引的字符串内使用定界符,那说明你可能是挑错了定界符。不过在你无法或不希望更换

定界符的情况下。可以通过反斜线转义来引入这个字符的:

qw! yahoo\! google ask msn! ##将yahoo!作为一个元素包含进来。

qw{
   /usr/dict/words
   /home/rootbeer/.ispell_english
}
#要是只能以斜线为定界符,这个列表将会变得相当臃肿难读。而且代码的编写和维护都很麻烦,所以不

同的定界符用在不同的地方是有好处的。

赋值列表:
就像标量值可以赋值给变量一样,列表值也可以赋值到变量:
($fred, $barney, $dino) = ("flintstone", "rubble", undef);
左则列表中的三个变量会依次被赋予右侧列表中以应的值,相当于我们分别做了三次独立的赋值操作。
所以在Perl里互换两个变量的值相当容易。
($fred , $barney) = ($barney, $fred); #互换两者的值
($betty[0], $betty[1]) = ($betty[1], $betty[0];

多出来的变量将被设成undef
($fred , $barney) = qw< flintstone rubble slate granite>; #忽略掉末尾两个元素
($wilma, $dino) = qw[ flintstone] #$dino被设为undef

明白了列表赋值,你便可以用如下代码来构建一个字符串数组:
($rocks[0],$rocks[1],$rocks[2],$rocks[3]) = qw/talc mica feldspar quartz/;

不过,当你希望引用整个数组时,Perl提供了一个比较简单的记法。只要在数组名之前加上@(at)字符(

后面没有检索用的方括号)就可以了。你可以将它读作"all of the"(全部的,所有的),所以@rocks

可以读作“所有的rocks"
@rocks = qw/ bedrock slate lava/;
@tiny = ()  #空列表
@giant = 1..1e5; #包含100,000个元素的列表
@stuff = (@giant, undef, @giant); #200,001个元素的列表
$dino = "granite";
@quarry = (@rocks, "crushed rock", @tiny, $dino)
将某个数组复制到另一个数组时,仍然算是列表的赋值运算,只不过这些列表是存储在数组里而已。

@copy = @quarry; #将一个数组中的列表复制到另一个数组。

pop 和 push 操作符:

要新增元素到数组尾端时,只要将它存放到更高的索引值对应的新位置就行了,一般的Perl程序员是不

太用索引的。
我们常把数组当成堆栈来用,这时新增和删除操作都在列表的右手边(就是数组里位于“最后面”的那一

端。也就是索引最高的那一端)发生,因为这类操作经常发生,所以有自己专用的函数。

 

pop操作符可用来取出数组中最后一个元素,同时返回该元素值:
@array = 5..9;
$fred = pop(@array); #$fred 变成9,@array现在是(5,6,7,8)
$barney = pop @array; #$barney变成8,@array现在是(5,6,7)
pop @array;  
现在是(5,6),7被抛弃了
push(@array, 0); 
现在是(5,6,0)
push @array, 8;  
现在是(5,6,0,8)
push @array, 1..10; 
得到了10个新元素
@others = qw/ 9 0 2 1 0/;
push @array, @others;  
又得到了5个新元素(共19个)

阅读(627) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~