文章目录
一、foreach结构与默认变量$_
foreach循环是为了对整个数组和列表中的标量进行处理,逐项遍历其中的值,依次迭代(循环过程)。这一点与SystemVerilog语言中的foreach循环用法有所区别。
foreach $rock(qw/bedrocks slate lava/){
print $rock . "\n"; #依次打印三个列表元素变量
}
说明:
- 循环时,控制变量(即$rock)都会从列表中取得新的值。第一次执行时控制变量值为“bedrocks”,第三次时,值为“lava”。
- 控制变量的作用范围仅限于foreach循环内。循环结束时,变量任保持循环之前的值;如果之前未被赋值,默认为undef。
- 控制变量可省略,Perl提供了默认控制变量$_。在许多情况下,Perl未告知使用哪个变量时,Perl都会使用默认变量$_。
代码示例:
#!/usr/bin/perl
$rock = "shirk"; #froeach循环外先声明$rock变量——区别于控制变量
print "$rock\n";
@rocks = qw(bedrocks slate lava);
print "@rocks\n";
foreach $rock(@rocks){
print $rock . "\n"; #依次打印三个列表元素
}
print "$rock\n"; #打印循环外的$rock变量值——shirk
#在foreach循环中使用范围操作符——数字列表
foreach (1..10){
print $_ . "\n"; #控制变量省略 —— $_为默认控制变量
}
$_ = "Hello";
print; #未告知使用变量,打印默认变量$_
print "\n";
@array = 5..9; #声明数组
foreach(@array){
print $_ . "\n";
}
编译运行:
shirk
bedrocks slate lava
bedrocks
slate
lava
shirk
1
2
3
4
5
6
7
8
9
10
Hello
5
6
7
8
9
二、函数操作符——用法规则
2.1、pop与push操作符——数组尾端
pop移除操作:
- 取出数组尾端最后一个元素并将其作为返回值返回;
- 如果数组是空的,直接返回undef;
- pop后面加不加括号都可以;
push添加操作:
- 添加一个元素(或一串元素或数组)到数组尾端;
- push后面加不加括号都可以;
注意:push的第一个参数或者pop的唯一参数都必须要是要操作的数组变量。
代码示例:
#!/usr/bin/perl
@array = 5..9; #声明数组
foreach(@array){
print $_ . "\n";
}
$fred = pop(@array); #pop_删除最后一个元素
print "@array\n";
print $fred . "\n";
$barney = pop @array; #括号可以不写
print $barney . "\n";
pop @array; #只删除最后一个值7,未做返回
print "@array\n";
push(@array,0); #push_在后端添加元素0
print "@array\n";
push @array,8; #添加元素8
push @array,3..5; #添加元素3,4,5
print "@array\n";
@others = qw(9 0 2 1 0);
push @array,@others; #添加列表
print "@array\n";
编译运行:
5
6
7
8
9
5 6 7 8
9
8
5 6
5 6 0
5 6 0 8 3 4 5
5 6 0 8 3 4 5 9 0 2 1 0
2.2、shift与unshift操作符——数组开头
shift移除操作与unshift添加操作:
- 用法同pop与push类似,对于一个空的数组变量shift操作会返回undef。
代码示例:
#!/usr/bin/perl
@array = qw#dino fred barney#;
print "@array\n";
$m = shift(@array); #去掉开头第一个元素dino赋给$m
print "@array\n";
print $m . "\n";
$n = shift @array; #$n为fred
$o = shift @array; #$o为barney
print "@array\n"; #此时@array为空列表
unshift(@array, 5);
print "@array\n"; ###添加5
unshift @array,4;
print "@array\n"; ###4,5
@others = 1..3;
unshift @array, @others;
print "@array\n"; ###1,2,3,4,5
编译运行:
dino fred barney
fred barney
dino
#空列表
5
4 5
1 2 3 4 5
2.3、reverse倒序与sort排序——整个数组/列表
reverse倒叙操作:
- 读取列表/数组的值,并按相反的次序返回。范围操作符(…)与reverse操作并用可实现地递减操作。
sort排序:
- 根据字符的内部ASCII编码顺序进行排序。字符代码点的排序想当怪异,对于数字排序需要进行特殊处理。
- 高级排序操作,见十二章。
代码示例:
#!/usr/bin/perl
@fred = 6..10;
@barney = reverse(@fred);
print "@barney\n"; #倒序输出10,9,8,7,6
@wilma = reverse 6..10; #括号可以不写
print "@wilma\n"; #倒序输出10,9,8,7,6
@bill = 1..10;
print "@bill\n";
@bill = reverse @bill; #必须存于其他数组再行打印
print "@bill\n";
@rocks = qw?bed slate horse giant?;
@sorted = sort(@rocks); #排序
print "@sorted\n"; #首字目顺序排列
@back = reverse sort @rocks; #倒序输出
print "@back\n";
print "@rocks\n";
@rocks = sort @rocks; #括号可以不写
print "@rocks\n";
@numbers = (20,10,9,2,1);
print "@numbers\n";
@out = sort @numbers; #按对应的ASUCII码大小进行排序
print "@out\n"; #输出1 10 2 20 9
@out = sort {$a<=>$b} @numbers; #砖石操作符
print "@out\n"; #大小顺序排序1 2 9 10 20
print "@numbers\n";
@numbers = sort {$a<=>$b} @numbers;
print "@numbers\n"; #大小顺序排序
编译运行:
10 9 8 7 6
10 9 8 7 6
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
bed giant horse slate
slate horse giant bed
bed slate horse giant
bed giant horse slate
20 10 9 2 1
1 10 2 20 9
1 2 9 10 20
20 10 9 2 1
1 2 9 10 20
三、列表上下文与标量上下文
在Perl中,同一个表达式出现在不同的地方会有不同的意义,要么希望它返回一个标量,要么希望它返回一个列表。表达式所在的位置,Perl期望得到什么,那就是该表达式的上下文:
42 + something; #这里的something必须是标量
sort something; #这里的something必须是列表
在Perl中,表达式总是根据所需要的上下文返回对应的值。以数组的”名称“为例:在列表上下文中,它会返回元素的列表;在标量上下文中,则会返回数组中的元素个数:
#!/usr/bin/perl
print "Hello\n";
@people = qw(fred barney bat); #列表
@sorted = sort @people; #列表上下文—名称充当列表——返回元素列表
$number = 42 + @people; #标量上下文—名称充当标量——返回元素个数
print "@sorted\n";
print "$number\n";
编译运行:
Hello
barney bat fred
45
3.1、在标量(列表)上下文中使用产生列表(标量)的表达式
#!/usr/bin/perl
#在标量上下文中使用产生列表的表达式
@backwards = reverse qw/yabba dabba doo /; #列表上下文
$backwards = reverse qw/yabba dabba doo /; #标量上下文——返回逆序字符串
print "@backwards\n";
print "$backwards\n";
#在列表上下文中使用产生标量的表达式
@fred = 6*7; #列表上下文——仅一个元素42
@barney = "hello" . ' ' . "world";
@wilma = undef; #列表上下文——仅有一个标量元素,默认值为undef,区别于下面的做法
@betty = (); #列表上下文——清空列表——空列表
说明:undef为标量值,所以将undef赋值给数组并不会清空数组。要清空数组的话,直接赋值一个空列表就可以了。
编译运行:
doo dabba yabba
oodabbadabbay
3.2、强制转换标量上下文——scalar伪函数
scalar伪函数并不是真正的函数,只是告诉perl强制引入标量上下文:
#!/usr/bin/perl
@rocks = qw{talc quarts jades obsidian};
print "How many rocks do yu have?\n";
print "I have @rocks rocks!\n"; #字符串中数组内插
print "I have ",@rocks," rocks!\n"; #错误,返回连续石头名称
print "I have ",scalar @rocks," rocks!\n"; #scalar——强制转换成列表上下文
编译输出:
I have talc quarts jades obsidian rocks!
I have talcquartsjadesobsidian rocks!
I have 4 rocks!
3.3、列表上下文中的< STDIN >
<STDIN>用法:
- 在标量上下文中:读取数据的一行;
- 在列表上下文中:读取数据的所有行,直到结束为止;
当输入数据来自某个文件时,它会读取文件的剩余部分。如果输入数据的来源是键盘,则通过Control+Z(Windows)来发送文件结尾。如果是Linux系统,则通过Control+D来结束。
#!/usr/bin/perl
print "现在开始输入:\n";
chomp($line = <STDIN>); #标量上下文——读取一行数据
print "$line\n";
print "继续输入\n";
chomp(@lines = <STDIN>); #列表上下文——(读入所有行,换行符除外)输入值存储在列表中,Ctrl+z退出输入
print "@lines\n";
编译运行:
现在开始输入:
my brother
my brother
继续输入
one is 1
hello
horse
^Z #Contral+Z结束输入
one is 1 hello horse