2007-07-30 阅读 136
#### 列表和数组
列表中每一个元素都是一个独立的标量值。这些值是有顺序的,也就是说,这些值从开头到最后一个元素有一个固定的序列。数组或者列表中的元素是编了号的,其索引从整数0 开始,依次增一,因此数组或者列表第一个元素的索引为0。
数组名字(本例中:fred)和标量是属于完全不同的命名空间(namespace)。同一程序也可以同时包含叫做$fred 的标量变量。Perl 将它们当作完全不同的事物来看待,不会混淆。
可以在任何能够使用标量变量(如$fred)的地方使用数组元素(如$fred[2])
下标可以是任何能返回数值的表达式。如果其值不为整数,则自动将其转换为小于它的最大整数值
如果下标超出了数组的范围,则其值为undef。
如果将一个元素存储在数组最后元素的后面的位置,数组会自动增长的。Perl 没有长度的限制,只要你有足够的内存。如果Perl 需要创建元素,则其值为undef。
有时需要知道数组最后一个元素的索引。刚才使用的rocks 数组,其最后一个元素的索引为$#rocks
由于经常将$#name 的值作为索引,像上面例子那样,因此,Larry 提供了一种简便方法:数组的负数索引值从最后一个元素开始。但不要认为这些索引是循环的。如果数组有3 元素,那有效的负数索引值是-1(最后一个元素),-2(中间的元素),-3(第一个元素)。实际上,几乎没有人使用除了-1 之外的其它的负数索引值。
---------------------------------------------------------------------------------------------------
数组是由括号括起来并且其元素由逗号分隔开的列表。这些值组成了数组的元素:
(1,2,3) #含有1,2,3 的列表
(1,2,3,) #同上,最后一个逗号被忽略
() #空列表-0 个元素
(1 ..100) #包含100 个整数的列表
最后一个例子使用了范围操作符(range operator)..,它创建了从左值到右值之间所有值的列表。
(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(fred barney betty wilma dino ) #同上,但输入更少
qw ! fred barney betty wilma dino !
qw# fred barney betty wilma dino # #有些像注释
qw( fred barney betty wilma dino )
qw{ fred barney betty wilma dino }
qw[ fred barney betty wilma dino ]
qw< fred barney betty wilma dino >
qw!Yahoo\! Google excite lycos ! #其中一个元素为:字符串yahoo!
qw{
/usr/dict/words
/home/rootbeer/.ispell_english
}
```
------------------------------------------------------------------
($fred, $barney, $dino) = (“flintstone”, “rubble”, undef);
($fred, $barney) = ($barney, $fred) #交换两个变量
($betty[0],$betty[1]) = ($betty[1],$betty[0]);
($fred, $barney) = qw ; #两个值被忽略了
($wilma,$dino) = qw[flintstone]; #$dino 为undef
($rocks[0],$rocks[1],$rocks[2],$rocks[3]) = qw/talc mica feldspar quartz/;
@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; #将一个数组中的值拷贝的另一个数组中
-------------------------------------------------------------------------
@array = 5..9;
$fred = pop(@array); #$fred 得到9,@array 现在为(5,6,7,8)
$barney = pop @array; #$barney gets 8, @array 现在为(5,6,7)
pop @array; #@array 现在为(5,6)(7 被丢弃了)
push(@array,0); #@array 现在为(5,6,0)
push @array,8; #@array 现在为(5,6,0,8)
push @array,1..10; #@array 现在多了10 个元素
@others =qw/9 0 2 1 0 /;
push @array,@others; #@array 现在又多了5 个元素(共有19 个)
@array = qw# dino fred barney #;
$m = shift (@array); #$m 得到“dino”, @array 现在为(“fred”, “barney”)
$n = shift @array; #$n 得到”fred”, @array 现在为(“barney”)
shift @array; #@array 现在为空
$o = shift @array; #$o 得到undef, @arry 仍为空
unshift(@array,5); #@array 现在为(5)
unshift @array,4; #@array 现在为(4,5)
@others = 1..3;
unshift @array, @others; #array 现在为(1,2,3,4,5)
--------------------------------------------------------------------------------------------
$email =“fred@bedrock.edu”; #错误!将会替换@bedrock
$email =“fred\@bedrock.edu”; #正确
$email =‘fred@bedrock.edu’; #另一种方法
@fred = qw(eating rocks is wrong);
$fred = “right”; #我们将打印“this is right[3]”
print “this is $fred[3]\n”; #打印出“wrong”使用$fred[3]
print “this is ${fred}[3]\n”; #打印出“right”(由花括号分开)
print “this is $fred”. “[3]\n”; #正确(两个字符串,右. 分开)
print “this is $fred\[3]\n”; #正确(利用反斜线转义)
----------------------------------------------------------------------------------------
foreach $rock (qw/ bedrock slate lava /){
print “One rock is $rock.\n”; #打印出3 种rocks
}
@rocks = qw/ bedrock slate lava /;
foreach $rocks(@rocks){
$rock = “\t$rock”; #@rocks 的每一个元素前加入一个tab
$rock . = “\n”; #每一个元素后加一个换行符
}
print “The rocks are:\n”,@rocks; #每一个元素都被缩进了,并且一个元素占一行
-----------------------------------------------------------------------------------------
foreach(1..10){ #使用默认的变量$_
print “I can count to $_!\n”;
}
$_ =“Yabba dabba doo\n”;
print; #打印出默认变量$_。
------------------------------------------------------------------------------------------
@fred = 6 ..10;
@barney = reverse (@fred); #得到10,9,8,7,6
@wilma = reverse 6 ..10; #同上,没有使用额外的数组
@fred = reverse @fred; #将逆转过的字符串存回去
reverse @fred; #错误,没有改变@fred 的值
@fred = reverse @fred; #改变了@fred 的值
------------------------------------------------------------------------------------------
@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
sort @rocks; #错误,不会修改@rocks
@rocks = sort @rocks; #现在@rocks 值是经过排序的
```
本节是本章中最重要的章节。事实上,是整本书的最重要一节。可以毫不夸张地说,你的整个Perl 职业生涯都是建立在对本节的理解之上。如果之前的章节你都未认真阅读,那本章千万不能马虎。
42 + something #something 必须是标量
sort something #something 必须是列表
@people = qw( fred barney betty );
@sorted = sort @people; #列表context:barney , betty, fred
$number = 42 + @people; #标量context:42+3,得到45
@list = @people; #3 个People 的列表
$n = @people ; #数字3
```
List-Producing 表达式
@backwards = reverse qw / yabba dabba doo /;
#返回doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo /;
#返回oodabbadabbay
$fred = something; # 标量context
@pebbles = something; #列表context
($wilma,$betty) = something; #列表context
($dino) = something; #列表context
```
让我们看看已经出现过的一些别的表达式及其context。下面是一些标量context:
$fred = something;
$fred[3] = something;
123 + something;
something + 654
if(something){… }
$fred[something] = something;
下面是一些列表context:
@fred = something;
($fred, $barney) = something;
($fred) = something;
push @fred, something;
foreach $fred(something)
sort something
reverse something
print something
```
------------------------------------------------------------------------------------------------
Scalar-Producing 表达式
@wilma = undef; #OOPS!得到一个元素的列表(undef),不同于下面的例子
@betty = (); #将数组置空的正确方法
```
------------------------------------------------------------------------------------------
@rocks = qw(talc quartz jade obsidian);
print “How many rocks do you have?\n”;
print “I have ”, @rocks, “rocks!\n”; #错误,输出rocks 的名字
print “I have ”, scalar @rocks, “rocks!\n”; #正确,输出其数字
```
------------------------------------------------------------------------------------------
在列表Context 中
当输入来源于一个文件时,它将读入文件的剩余部分。但如果输入来源于键盘,那文件结束符(end-of-file)是怎样输入的呢?在Unix 或者类似的系统中,包括linux, Mac OS X,通常可以输入CTRL +D来表明输入已经结束。Perl 会忽略这个字符,因此它将在屏幕上显示出来。在DOS/WINDOWS 系统中,使用CTRL +Z。
@lines = ; #读入所有的行
chomp = (@lines); #去掉所有的换行符
但更常见的做法是:
chomp (@lines = ); #读入所有的行,不包括换行符
```
perl 学习笔记