学习perl(2)

 

学习Perl(2)
列表和数组
1)特殊的数组索引值
假如对索引值超过数组尾端的元素赋值,数组将会依需要自动扩大---只要有可用的内存配置给Perl,数组的长度是没有上限的。必要时,插入的元素会自动产生,并设成undef值。把$#name当成索引值的做法十分常见,还可以 从数组尾端往回计数“负数数组索引值”
2)列表直接量
(1,2,3,) (1,2,3) (1..100) ($a,17) (“fred”, “betty”) 几个示例
qw(quoted word)缩写
Perl程序里,经常要建立简单的单词列表,这时可以使用qw简写,省去键入一堆额外引号的时间:qw/ fred betty / 界定符还可以是其他的,如!{<[
qw列表中,不能像双引号内的字符串一样使用n$fred;因为qw是一种引号,所以不能将注释放在qw列表中。
3)列表的赋值
因为列表是在赋值运算开始之前建立的,所以在Perl里互换两个变量的值相当容易:
($fred,$betty) = ($betty,$fred); #互换两者的值
引用整个数组时,只要在数组之前加上一个@符号(而且后面没有出现索引的方括号)就可以了,如:@rocks = qw/ bedrock slate / ;
pop
push操作符:把数组当成堆栈来用是很常见的做法,这时,项目的新增和移除都是在右手边进行的(就是数组里位于“最后面”的那一端)。
pop操作符可用来取出数组中最后一个元素并且将它返回:
@array = 5..9; $fred = pop(@array); #$fred变成9@array现在变成(5,6,7,8)
如果数组是空的,那么pop不会变动它,而且会返回undef
push操作符和pop相反,它会添加一个元素或者一串元素到数组的尾端:push(@array,0);
注意:push的第一个参数或pop的唯一参数必须是数组变量,对列表直接量进行pushpop操作是毫无意义的。
shiftunshift操作符:对数组的“开头“进行相应的操作:
pop类似,对于一个空的数组变量,shift会返回undef

4)foreach控制结构
foreach循环会逐项处理列表的值,每次对一个值执行循环里的操作:
#!/usr/bin/perl -w

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

print "One rock is $rock.n";

}
改进后Perl所支持的做法:
#!/usr/bin/perl -w

@rocks = qw/ bedrock slate lava /;

foreach $rock (@rocks) {

$rock = "t$rock";

$rock .= "n";

}

print "The rocks are:n", @rocks;

Perl
最爱的默认变量$_
假如你在foreach循环的开头省略了控制变量,Perl会使用它最爱的默认变量$_
#!/usr/bin/perl -w

foreach (1..10) {

print "I can not count to $_!n";

}
#!/usr/bin/perl -w

$_ = "Yabba dabba doon";

print;

reverse
操作符:reverse会读取列表的值(可能来自数组)并依相反的次序返回该列表
#!/usr/bin/perl -w

@fred = 6..10;

@fred = reverse @fred;

print "The freds now are: @fred.n";
注意:reverse操作符会返回次序相反的列表,但它并不会影响自己的参数,所以假如返回值没有被赋值到任何地方,它将毫无意义:
reverse @fred ; #错:不会改变@fred @fred = reverse(@fred); #好多了

类似reverse的操作符sort,排序的顺序就是ASCII编码的顺序
对数组排序时,必须将排序的结果存回数组:@rocks = sort @rocks;
#!/usr/bin/perl -w

@fred = 97..102;

@fred = sort @fred;

print "The freds now are: @fred.n";

5)标量上下文与列表上下文
“上下文”指的就是表达式所出现的位置。解析表达式时,Perl会希望它是“标量值”或“列表值”的其中之一,此处,Perl所希望的,就称为表达式的上下文。
Perl中,表达式的返回值一定会符合它们的上下文。以数组的“名称”为例:在列表上下文中,它会产生元素的列表;在标量上下文中,它会返回数组中元素的个数:

@people = qw( fred barney betty );
@sorted = sort @people; #
列表上下文: barney betty fred)
@number = 42 + @people; #
标量上下文:42 + 3等于45
@list = @people; #
包含3个人名的列表

$n = @people; #数字3
#!/usr/bin/perl -w

@people = qw( fred barney betty );

@sorted = sort @people;

@number = 42 + @people;

@list = @people;

$n = @people;

print "The number of people are : $n.n";

print "The list ; @list.n";

print "The number : @number.n";

printf "The sorted : @sorted.n";
注意:但请不要立刻得出结论,在标量上下文中一定会得到列表上下文中所返回元素的个数。

在标量上下文中使用产生列表的表达式
除非有人提出别的实现方式,否则sort在标量上下文中总是会返回undef
在列表上下文中,reserve会返回反序过的列表;在标量上下文中,它则会返回反序过的字符串:
#!/usr/bin/perl -w

@backwards = reverse qw/ yabba dabba doo /;

print "The list of backwards are: @backwards.n";

$backwards = reverse qw/ yabba dabba doo /;

print "The scalar of backwards are: $backwards.n";
不要被只有一个元素的列表给骗了,($dino) = something;这个还是列表上下文。只要元素是赋值给列表的(不管元素的个数),它就是列表上下文。假如你将元素赋值给数组,它也还是列表上下文。

在列表上下文中使用产生标量的表达式
这里的转换十分直接:假如表达式的求值结果不是列表值(也就是标量值),则标量值会被自动提升为含有单一元素的列表:@fred = 6 * 7; #变成含有单一元素的列表{42}
空列表的正确赋值法: @betty = (); 而不是:@betty = undef;
因为undef是标量值,所以将undef赋值给数组无法清空该数组。直接使用空列表赋值可能是比较好的办法。
@fred = 6 * 7;

print "The result of fred is : @fred.n";

@barney = " Hello" . ' ' . "world";

print "The result of barney is :@barney.n";

@betty = ();

print "The result of betty is : @bettyn";

强制指定标量上下文
有时候,需要在Perl期望列表上下文的时候,强制指定标量上下文,此时可以使用假函数scalar,它不是真的函数,只是用来告诉Perl必须提供标量上下文:
#!/usr/bin/perl -w

@rocks = qw( talc quartz jade obsidian );

print "How many rocks do you have?n";

print "I have ",scalar @rocks," rocks!n";
print "I have ", @rocks," rocks!n"; #
错,这会输出各种石头的名称

列表上下文中的

在标量上下文中会返回输入数据的下一行;在列表上下文中,则会返回剩余的各行,直到文件结尾为止,所返回的每一行都将成为列表中单独的元素。
输入数据的来源是键盘时,产生文件结尾符号的方式:UNIX及其类似的系统,键入Ctrl + D、对于DOSWindows之类,键入Ctrl + Z
@lines = ; #读取所有数据行 chomp(@lines); #忽略所有换行符
或者更简洁的 chomp(@lines = ); #读取所有数据行,但不包括换行符



习题:
1)读入一串字符串(每行一个),直到文件结尾为止,然后以相反顺序输出这个列表。(如果输入来自键盘,键入Ctrl + DCtrl + Z来结束输入)
#!/usr/bin/perl -w

print "Please enter a tring,each line for one:n";

print "When you finished it,please enter Ctrl + Dn";

chomp(@lines = );

@lines = reverse @lines;

print "The result is ; @lines.n";
参考答案如下:
#!/usr/bin/perl -w

print "Enter some lines,then press Ctrl-D:n";

@lines = ;

@reverse_lines = reverse @lines;

print @reverse_lines;
#!/usr/bin/perl -w

print "Enter some lines,then press Ctrl-D:n";

print reverse;
2
)读入一串字符串(每行一个),直到文件结尾为止,然后根据每一个数字,输出如下名单(fred betty dino wilma pebbles bamm-bamm)中相应的人名。
#!/usr/bin/perl -w

print "Please enter some numbers,each line for one,then enter Ctrl + D:n";

@names = qw / fred betty dino wilma pebbles bamm-bamm /;

chomp(@values = );

foreach (@values) {

print "$names[$_ -1 ]n";

}
参考答案如下:
#!/usr/bin/perl -w

print "Please enter some numbers,each line for one,then enter Ctrl + D:n";

@names = qw / fred betty dino wilma pebbles bamm-bamm /;

chomp(@values = );

foreach (@values) {

print "$names[$_ -1 ]n";

}
3

#!/usr/bin/perl -w

print "Pleas enter lines,each line for one string,then enter Ctrl + D:.n";

print sort();
参考答案如下:
#!/usr/bin/perl -w

chomp(@lines = );

@sorted = sort @lines;

print "@sortedn";
让每一行分开显示的做法: print sort ;


子例程
1)定义子例程
定义你自己的子例程时,将会用到关键字sub、子例程的名称(不含&符号)以及(花括号内)经缩排的构成子例程主体的程序代码块:(子例程的定义可以放在程序中的任何地方)
#!/usr/bin/perl -w

sub marine {

$n += 1;

print "Hello,sailor number $n!n";

}

2
)调用子例程
任何表达式中只要使用了子例程的名称(加上&符号),就会调用子例程:&marine;
3
)返回值
Perl中,任何子例程都有返回值,子例程并没有分成有返回值和没有返回值两种。
#!/usr/bin/perl -w

sub sum_of_fred_and_barney {

print "Hey,you called the sum_of_fred_and_barney subroutine!n";

$fred + $barney;

}

$fred = 3;

$barney = 4;

$c = &sum_of_fred_and_barney;

print "$c is $c.n";

$d = 3 * &sum_of_fred_and_barney;

print "$d is $d.n";

sub larger_of_fred_and_barney {

if ($fred > $barney){

$fred;

} else {

$barney;

}

}

$fred = 3;

$barney = 4;

$c = &larger_of_fred_and_barney;

print "The larger is $c.n";

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21256317/viewspace-776980/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/21256317/viewspace-776980/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值