legend

思考助我前行

perl学习日记3 列表和数组

1.    列表和数组

关键是理解数组,它的意义和c语言时一样的,不过它更猛,a[0]a[1]可以存储不同类型的值,帅撒?

1.1      访问数组元素

其实perl访问数组的方法和c语言时一样的,但是它不需要访问之前的那个定义过程,不需要定义类型,不需要定义大小,还要要注意的是如果访问到了没有初始化的数组,返回的可是undef?还记得undef

$blank = $fred [142_857]   #这样系统时允许的,不过由于该数组元素没有初始化,得到的时undef;

1.2      有趣的索引值

perl里面数组还是有大小的,不过这个大小时动态的,如果你定义了a[88],那么它的大小就是89,如果你直接定义a[10000],那么它的大小就是10001,可以通过$#a来直接得到数组的最后的索引值

所以:a[$#a]即代表最后一个元素,perl中更牛逼的是可以用a[-1]直接得到最后一个元素,同样a[-2]是倒数第二个,如果该数组只有一个元素,用a[-2]则会导致错误,通常我们只用a[-1]取最后一个。

1.3      列表

数组是由括号括起来并且其元素由逗号分隔开的列表。

例子:

1,2,3)或者(1,2,3,)都代表含有1,2,3的列表

()代表0个元素的空列表

1 .. 100#代表1100的所有整数,这个范围操作符..必须要求两边是整数,否则转换为整数,必须左边小于右边,否则为空列表,而且只能递增1.

1.3.1.Qw简写

(“fefd”,”legend”,”wang”)

实践表明,字符串的列表(如上例) Perl 中经常使用。有一种简便的方法可以不用输入大量的引号而达到类似的功能那就是使用 qw

qw(ferd legend wang) 注意括号里面时由空格,制表符,换行来分割的,而且分割之后的东西不管里面有什么都是普通的字符,(//)例外,会把它视为(/),而其他所有东西包括(/')都是不转义的,所以现在有个问题,这种方式不能表示带空格的字符串?因为没有能把空格转义的方式。

例子:

@legend = qw {i love china, 'do/ you'};

foreach(@legend)

{

        print $_."/n";

}

结果:

legend@ubuntu:~/data/study/perl$ perl 3.4

i

love

china,

'do/

you'

前面两个例子是用括号作为分界符, Perl 允许使用任何标点符号作为分界符。下面是一些常用的类型:

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!

1.4      列表赋值

($fred, $barney, $dino) = (“flintstone” “ rubble” undef);

 ($fred, $barney) = ($barney, $fred)         #交换两个变量的值

如果=左边个数不等于右边个数,如果值多了,就忽略,如果变量多了,就把多的赋值为undef

例子:

@rocks = qw / bedrock slate lava /;

@tiny = ();            #空表

@giant = 1..1e5;    #包含 100,000 个元素的表

@stuff = (@giant,unfef,@giant);                 #包含 200,001 个元素的表,注意列表里如果有数组,应该在赋值之前把该数组展开为其值,因为数组变量的值只能是标量,不能是任何变量(参考例子3.4.1)。

@dino = “granite”;

@quarry = (@rocks, “crushed rock” @tiny, $dino); #将五个元素赋给了@quarry,因为@tiny展开是空表,没有东西,千万别以为它是undef

分析一个经典例子(3.4.2),弄清楚它就相当于弄清楚了undef的真正含义:

@showEmptyArray = ();

@b = ("legend1",@showEmptyArray,"legend2",@showUndefArray,"i think/,you love him",$showUndefBianLiang,"Do you understand?",$showUndefNumber+1);

foreach(@b)

{

        print $_."/n";

}

结果:

legend@ubuntu:~/data/study/perl$ perl 3.4.2

legend1

legend2

i think,you love him

 

Do you understand?

1

看懂了没?重说下undef的含义,如果是变量,其值可能为0或者空串,如果是数组,其值为空表,所以@showEmptyArray@showUndefArray展开之后都是空串,而$showUndefBianLiang展开之后为空串,自然要占一个元素的位置。而最后一个$showUndefNumber+1展开之后是0+11,明白?

 

@copy = @quarry   #复制数组

1.4.1.poppush操作

@array = 5..9;

$fred = pop(@array); #$fred 得到9@array 现在为(5678

$barney = pop @array; #$barney gets 8, @array 现在为(5,6,7

pop @array; #@array 现在为(56(7 被丢弃了)

 

push(@array,0); #@array 现在为(5,6,0)

push @array,8; #@array 现在为(5608

push @array,1..10; #@array 现在多了10 个元素

@others =qw/9 0 2 1 0 /;

push @array,@others; #@array 现在又多了个元素(共有19 个)

1.4.2.shiftunshift操作

@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

1.5      将数组插入字符串

 

@rocks = qw{ flintstone slate rubble };

print “quartz @rocks limestone/n”; #输出为rocks 由空格分开,其中@rocks的三个元素之间用空格隔开,而首位两个前后都没有空格

 

$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”; #正确(利用反斜线转义)

 

1.6      foreach控制语句

foreach $rock (qw/ bedrock slate lava /){

print “One rock is $rock./n”; #打印出rocks

}

 

领会下面的例子:

#!/usr/bin/perl

@rocks = qw /legend1 legend2 legend3/;

print @rocks;

print "over/n";

foreach $rock(@rocks)

{

        $rock = "/t".$rock;

        $rock .="/n";

 

}

print "the rocks are:/n",@rocks;

结果:

legend@ubuntu:~/data/study/perl$ perl 3.6

legend1legend2legend3over

the rocks are:

       legend1

       legend2

       legend3

该例说明了两件事:

1控制变量不是这些列表元素中的一个拷贝而是这些元素本身。也就是说,如果在循环中修改这个变量,那原始列表中的元素也会被修改

2当循环结束时$rock 的值为多少呢?其值同循环开始之前相同。foreach 循环中控制变量的值会被Perl 自动保存和恢复。当循环进行时,是没有办法改变其值的。循环结束时,变量的值会回到循环开始前,如果没有值则为undef。这意味着如果有一个变量和控制变量有相同的名字:$rock,不用担心会混淆它们。

1.6.1.默认变量$_

foreach(1..10){ #使用默认的变量$_,直接省略了控制变量

print “I can count to $_!/n”;

}

 

$_ =“Yabba dabba doo/n”;

print; #打印出默认变量$_

1.6.2.Reverse逆转列表或者数组再返回,但是传入的数组没有变化

@fred = 6 ..10;

@barney = reverse (@fred); #得到109876

@wilma = reverse 6 ..10; #同上,没有使用额外的数组

@fred = reverse @fred; #将逆转过的字符串存回去

1.6.3.Sort排序,无论数字还是字符,都按ASC序排,通常数字这样排序没有意义

@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; #得到100101102979899

 

reverse是一样的,也不改变传入参数的值

1.7      标量和列表上下文

@people = qw( fred barney betty );

@sorted = sort @people; #列表contextbarney , betty, fred

$number = 42 + @people; #标量context42+3,得到45

@list = @people; #3 People 的列表

$n = @people ; #数字3

1.7.1.在标量Context 中使用List-Producing 表达式

@backwards = reverse qw / yabba dabba doo /;

#返回doo, dabba, yabba

$backwards = reverse qw/ yabba dabba doo /;

#返回oodabbadabbay

如果你见到神人写出

$backwards = sort qw/ yabba dabba doo /;

那么其实$backwards undef

例子3.7.1

 

 

#!/usr/bin/perl

$a = reverse qw /legend1 legend2 legend3/;

print $a."/n";

$b = qw /legend1 legend2 legend3/;  #对标量进行赋值,取列表的最后一个元素

print $b."/n";

($c) = qw /legend1 legend2 legend3/;   #对列表进行赋值

print $c."/n";

结果:

legend@ubuntu:~/data/study/perl$ perl 3.7.1

3dnegel2dnegel1dnegel

legend3

legend1

1.7.2.在列表Context 中使用Scalar-Producing 表达式

仔细品味下面的例子:

#!/usr/bin/perl

@a = undef;             #undef赋值了,所以@a为有一个元素的列表

$aNum = @a;            #上下文环境为标量,所以值为1

print $aNum."/n";

print "the /@a is:",@a,"over","/n";   #上下文环境是列表,所以显示为列表的undef值空串

print "the /@a is:".@a."over"."/n";        #标量环境,为1

@b = ();                              #空串赋值,所以@b没有元素

$bNum = @b;                      #上下文环境为标量,所以值为0

print $bNum."/n";

print "the /@b is:",@b,"over","/n";

print "the /@b is:".@b."over","/n";

结果:

legend@ubuntu:~/data/study/perl$ perl 3.7.2

1

the @a is:over

the @a is:1over

0

the @b is:over

the @b is:0over

1.7.3.强制转换为标量Context  在列表前面加上scalar

@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”; #正确,输出其数字

1.8      <STDIN>在列表Context 

@lines = <STDIN>; #将输入读入列表context ,每行一个元素

如果是这样,你按完换行就是对下一个元素的输入,什么时候是个头呢,linux一般用ctrl+D结束。

 

常用用法:chomp (@lines = <STDIN>); #读入所有的行,不包括换行符,因为chomp能将每个元素最后的那个换行符去掉再赋值给相应元素。

阅读更多
个人分类: study_log
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭