列表指的是标量到有序集合,而数组则是存储列表到变量。列表指的是数据,而数组指的是变量。
数组或列表中到每个元素都有相应到数字作为索引,索引是从数字0开始到。
1、数组中元素到访问
$fred[0] = "yabba"; $fred[0] = "dabba"; $fred[0] = "doo";
数组的名字空间和标量的名字空间是分开的,也就是在统一个程序里可以有两个相同的数组变量名和标量变量名,
Perl是能区分开来的,但是为了程序的维护,最好还是不要这么做。可以把数组中的任何一个元素当作一个普通的标量变量来使用。
print #fred[0]; $fred[2] = "diddley"; $fred[1] .= "whatsis";
当索引号为小数时,会自动舍弃小数,无论正负。
$fred[1.3432432] = $fred[1];
如果从未对数组中某一个元素赋值,则其对应的值将会是undef。
2、特殊的数组索引值
假如索引值超过数组尾端的元素进行赋值,数组将会根据需要自动扩大,只要有可用的内存分配给Perl,数组的长度是没有上限的。如果在扩展过程中需要创建增补元素,那么它们的默认取值为undef。
有时想要找到最后一个元素到索引值,可以使用$#rocks。
$end = $#rocks; $number_of_rocks = $end +1; $rocks[$#rocks] = 'hard rock'; 且$rocks[-1] = 'hard rock'; #最后一个元素
3、列表直接量
范围操作符:..仅向上计数:(1..5) = (1,,2,3,4,5);
列表可以直接这样写:("fred", "barney", "betty", "wilma", "dino")
4、qw简写
("fred", "barney", "betty", "wilma", "dino") = qw(fred barney betty wilma dino)
Perl都会将其当成单引号内的字符串来处理,所以,在qw构建的列表中,不能像双引号内的字符串一样使用\n或$fred。其中的空白字符会被抛弃,然后剩下的就是列表的元素。
qw可以使用任何标点符号作为定界符。也可以使用反斜线转义。
5、列表的赋值
($fred,$barney,$dino) = ("flintstone", "rubble", undef);
利用列表来互换两个变量的值
($fred, $barney) = ($barney, $fred);
当列表内的值多于变量值时,多于的值会被抛弃;当变量值多于列表的值时,多余的变量会被赋值为undef(相当与数字0或空字符串)。
构建一个数组:
($rocks[0], $rocks[1], $rocks[2], $rocks[3]) = qw/talc mica fekspar quartz/;
引用数组时,在数组名前加个@
@rocks = qw/bedrock slate lava/; @tiny = (); #空列表 @giant = 1..1e5; #包含100000个元素的列表 @quary = (@rocks, "crushed rock", @tiny, $dino); @copy = @quary; #将一个数组的列表复制到另一个数组
6、pop和push操作符
这两个操作符都是针对数组的最后一个元素,pop是将最后一个元素取出,或是丢弃,或是赋值给某一个标量变量;push操作符,用于添加一个元素到数组到尾端。
@array = 5..9; $fred = pop(@array); #fred = 9 , @array = (5,6,7,8) $barney = pop @array; #barney = 8, @array = (5,6,7) pop @array; #@array = (5,6),7被丢弃若数组为空,则 pop什么也不做,直接返回undef 。
push(@array, 0); push @array, 8; push @array,1..100; #@array得到100个新元素 @other = qw/9 0 2 1 0/; push @array, @others;注意: push的第一个参数,或是pop 的那个唯一的参数,都必须是要操作的数组变量,对列表直接量进行压入或弹出操作是不可能到。
7、shift和unshift操作符
这两个操作符操作的是数组到开头到元素。
@array = qw#dino fred barney#; $m = shift(@array); #$m变成了“dino”,@array现在是("fred", "barney") $n = shift @array; unshift(@array, 5) #@array现在有多了一个元素,开头是5 unshift(@array, 4); #@array现在是(4,5) @other = 1..3; unshift @array, @others; #@array又变成了(1,2,3,4,5)和 pop类似,对于一个空的数组变量,shift会返回undef 。
8、字符串数组的内插
和标量一样,数组的内容同样可以被内插到双引号中。内插时,会在数组的各个元素之间自动添加分隔用的空格。
@rocks = qw{flintstone slate rubble}; print "quartz @rocks limestone\n"; #输出5种以空白隔开到石头数组被内插后,首尾都不会增添额外空格;为了有时避免数组内插
$email = "fred\@bedrock.edu"; = $email'[email protected]';
如果需要在某个标量变量后面接着写左方括号,你需要先将这个方括号隔开,它才不至于被识别为数组检索到一部分。做法如下:
@fred = qw(eating rocks is wrong); $fred = "right"; #我们想要说"this is right[3]" print "this is $fred[3]\n"; #用到了$fred[3],打印"wrong" print "this is $(fred)[3]\n"; #打印"right" print "this is $fred".[3]\n"; #同上 print "this is $fred\[3]\n"; #同上
9、foreach控制结构
foreach(循环)能逐项遍历列表中的值,依次迭代:
foreach $rock(qw/bedrock slate lava/){ print "one rock is $rock.\n";}
每次循环迭代,$
rock都会从列表中取得新的值,控制变量并不是列表元素的复制品。也就是说,加入在循环中修改了控制变量的值,也就同时修改了这个列表元素。@rocks = qw(bedrock slate lava); foreack $rock(@rocks){ $rock = "\t$rock"; #在@rocks的每个元素前加上跳格符 $rock .= "\n";} #同时在末尾加上换行符 print "The rocks are: \n", @rocks; #各自占一行,并使用缩排
当$
rock在这里使用完后,它会回复它原来到变量值,也就是说可以在程序中使用已有的标量变量来作为foreach的变量。
10、Perl的老地方$_
在foreach的开头没有使用控制变量,系统会默认使用$_这个变量。
foreach (1..10){ #系统默认使用$_来作为控制变量 print "I can count to $_.\n";}以后在未告知使用哪个变量时, Perl 往往会默认使用这个变量。
print; #默认打印的就是$_
11、reverse操作符
该操作符会读取列表的值,并按照相反到次序返回该列表。
@fred = 6..10; @barney = reverse @fred; #@barney = {10,9,8,7,6} @wilma = reverse 6..10; @fred = reverse @fred; #逆序后到数组放回原来到数组 reverse @fred #错误,必须有返回
12、sort操作符
读取列表的值,而且会根据内部到字符编码的顺序,对它们进行排序。对ACSII编码到字符串而言,排序的规则就是ASCII码序
@rocks = qw/bedrock slate rubble granite/; @sorted = sort(@rocks) #得到bedrock, granite, rubble, slate @back = reverse sort @rocks; #逆序后从slate 到bedrock排列 @rocks = sort @rocks; #将排序后到结果存回至@rocks @numbers = sort 97..102 #得到100,101,102,97,98,99
从最后一个例子可以看出,将数字当成字符串来排序,这样到结果会不太对,因为根据默认到规则,任何以
1开头的到字符串会被排在以9 开头到字符串之前。sort @rock; #错误 @rock = sort @rock;
13、标量上下文与列表上下文
在Perl中,表达式总是根据所需要到上下文返回对应的值。以数组名称为例,在列表上下文中,他会产生元素的列表;但是在标量上下文中,则会返回数组中元素到个数。
sort在标量上下文中返回undef,在列表上下文中返回排序后到列表。
reverse在标量上下文中返回逆序后到字符串,在列表上下文中返回逆序后的列表。
@backwards = reverse qw/yabba dabba doo/; #会变成doo,dabba,yabba $backwards = reverse qw/yabba dabba doo/; #会变成oodabbadabbay ($dino) = something; #列表上下文 $dino = something; #标量上下文 @betty = (); #清空数组
14、强制制定标量上下文
偶尔在列表上下文的地方,想要强制引入标量上下文,这可以使用为函数scalar。它可不是真正到函数,只不过告诉Perl这里要切换到标量上下文。
@rocks = qw/talc quartz jade obsedian/; print "how many rocks do you have?\n"; print "I have", @rocks, "rocks!\n"; #错误,会输出各种石头的名称 print "I have", scalar @rocks, "rocks!\n"; #对了,打印出来的是石头种数
15、列表上下文中到<STDIN>
我们之前看过到<STDIN>操作符,在列表上下文中会返回不同的值。就像前面的,<STDIN>在标量上下文会返回输入数据的上下行;在列表上下文,则会返回所有剩下的行,知道文件结尾为止。返回的每一行都会成为列表中到每个元素。举例来说:
@lines = <STDIN>; #在列表上下文中读取标准输入
当输入数据来自某个文件时,它会读取文件的剩余部分。但是如果输入数据到来源是键盘,对于类Unix或类似的系统可以键入CTRL -D来告知系统,不会再有任何输入了。在DOS/WINDOWS系统中,使用CTRL -Z来告知系统。
加入运行程序到人在键入了三行数据之后又用适当到案件来表示文件结尾,最后得到到数组就会包含三个元素。每个元素都是以换行符结尾到字符串,因为这些换行符也是输入到内容。可以把数组直接交给chomp,它会自动去掉每个元素的换行符。
@lines = <STDIN>; #读入所有行 chomp(@lines); #去掉所有的换行符
不过更常见的做法是:
chomp(@lines = <STDIN>); #读入所有的行,换行符除外