分类:
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个)