版权声明:转载请说明出处! https://blog.csdn.net/qq_39556143/article/details/85176184
Perl其他控制结构
1. unless & until 控制语句
1.1 unless控制结构
在 if 条件语句中,只有当条件为真时,才执行某块代码,而unless条件语句,可以使得条件为假时,执行某块代码。
#!/usr/bin/perl
unless ($fred =~ /\A[A-Z_]\w*\z/i) { #除非条件为真,否则打印
print "The value of \$fred doesn't look like a Perl indefntifier name.\n";
}
#相同含义的if条件语句
if ($fred =~ /\A[A-Z_]\w*\z/i) {
#什么也不做
} else {
print "The value of \$fred doesn't look like a Perl indefntifier name.\n";
}
#unless也可以包含else语句
unless ($fred =~ /\A[A-Z_]\w*\z/i) { #除非条件为真,否则打印
print "The value of \$fred doesn't look like a Perl indefntifier name.\n";
} else {
print "The value of \$fred looks like a Perl indefntifier name.\n";
}
1.2 until控制结构
如果希望用到while循环的反条件,可以使用util语句
#!/usr/bin/perl
util ($j > $i) { #除非$j > $i,否则$j翻倍
$j *= 2;
}
1.3 表达式修饰符
- 为了进一步简化书写,表达式后面可以接一个用于控制其行为的操作符。
- 虽然修饰语句写在表达式的后面,但是首先执行修饰符,然后执行前面的表达式;
#!/usr/bin/perl
print "$n is a negative number.\n" if $n < 0; # print message if $n < 0
#相同功能的if语句
if ($n < 0) {
print "$n is a negative number.\n"
}
#其他类型的表达式修饰符
&error("invalid input") unless &valid("valid input");
$i *= 2 if $i < $j;
print " ",($n += 2) while $n < 10; #向执行$n += 2,将更新后的值输出
&greet($_) foreach @person;
1.4 裸块控制结构
- 裸块:naked block 指的是没有关键字或者条件表达式的代码块;
- 裸块就像while和for循环一样,不过只会执行一次;
- 裸块中声明的变量,其有效空间被限制在裸块内部。
#!/usr/bin/perl
#while循环
while ($n < 100) {
body;
body;
...
}
#naked block
{
body;
body;
...
}
2. elsif & 自增自减
2.1 elsif语句
- 当我们需要逐项检查一系列的条件表达式的时候,可以使用elsif语句进行匹配;
- 当对应分支的条件满足时,执行其后对应的程序块;
- 当分支数量过多时,程序会从头至尾依次比对,程序执行速度下降,建议采用其他方式;
- 注:分支关键字为elsif 不是elseif,不要问为什么,因为Larry说的算。
#!/usr/bin/perl
if (! defined $dino ){
expression0;
} elsif ($dino == "dino") {
expression1;
} elsif ($dino == "DINO") {
expression2;
} elsif ($dino == "Dino") {
expression3;
} else { #这里是用的是完整的else
expression4;
}
2.2 自增&自减
- 和其他语言类似,perl也存在自增和自减操作符 ++ --,含义简单不再赘述;
- perl中存在前置自增自减和后置自增自减 (preincrement & postincrement)
#!/usr/bin/perl
#preincrement
my $m = 5;
my $n = ++$m; #先执行自增操作,再执行赋值操作: $m = 6, $n = 6
$n = --$m; #先执行自减操作,再执行赋值操作: $m = 5, $n = 5
#postincrement
$n = $m++; #先执行赋值操作,再执行自增操作: $n = 5, $m = 6
$n = $m--; #先执行赋值操作,再执行自减操作: $n = 6, $m = 5
3. for循环控制结构
3.1 for控制结构
- perl的for循环结构和c语言的for循环结构类似,见下例。
- for和foreach在perl中被看做相同功能,看到其中一个就像看到另外一个;
- 通过其后的圆括号内是否包2个分号进行区分
- 包含两个分号 ? for :foreach。
#!/usr/bin/perl
for(initialization; test; increment) {
body;
body;
body;
}
#相同功能的while循环
initialization;
while (test) {
body;
body;
body;
increment;
}
#perl中for循环的三个操作都可以为空,当test为空时,连续出现的两个分号被看做死循环
for($i=0; ; ){
body;
#这是个死循环
}
#for & foreach 的秘密关系
for (1..10) { #perl自动将其转换为 foreach(1..10)
body;
...
}
foreach ($i = 0; $i < 100; $i++) { #perl自动将其转换为for($i=0; $i<100; $i++)
body;
...
}
#
3.2 循环控制语句
循环控制语句中包括三种循环控制操作符:last next redo
- last操作符
- 终止此次循环,和c语言的break类似
- 只能作用域本层循环
- next操作符
- 结束本次迭代,进入下次迭代,和c语言的continue类似
- 只能作用于本层循环
- redo操作符
- 重新开始此次迭代,c语言中没有类似的操作符
- 只能作用本层循环
下面的例子可以帮助我们熟悉以上三个循环控制操作符;
#!/usr/bin/perl
foreach (1..10) {
print "Iteration time: $_.\n";
print "plese choose: last next redo or other string";
chomp(my $choice == <STDIN>);
print "\n";
last if $choice =~ /last/i; #i=4时输入,不能看到数字5
next if $choice =~ /next/i; #i=4时输入,可以看到数字5
redo if $choice =~ /redo/i; #i=4时输入,连续看到两次数字4
print "this wasn't any of the choices"; #i=4时输入,正常完成循环
}
带标签的块
如果我们需要从内层循环退出外层循环,可以使用标签label
- label可以是数字,字母和下划线的组合,但是不能以数字开头;
- 为防止和其他变量或者函数从冲突,建议使用全大写来命名;
- label应该写在循环块的前面,格式: LABEL:
#!/usr/bin/perl
LINE: while(<>) {
foreach (split) {
last LINE if $_ =~ /__END__/; #遇到__END__时,结束此次循环
...
#next redo都可以使用这种方法,直接处理外层循环
}
}
4. 条件操作符
4.1 条件操作符
条件操作符,也可以叫做三目运算符 ?:
格式: expression ?if_true_exp:if_false_exp;
#!/usr/bin/perl
my $size = ($number > 100) ? "large":"samll";
#相同功能的if语句
if($number > 100) {
$size = "large";
} else {
$size = "small";
}
#如果三目运算符运用的熟练,可以让程序变得很简洁
my $size =
($number < 10) ? "samll" :
($number < 50) ? "middle" :
($number <100) ? "large" :
"extra-large";
4.2 逻辑操作符
perl的逻辑操作符 && ||
- 逻辑与 &&
- 例: a && b
- a 和 b 全为真,返回真,否则返回假
- a 为假时,不再判断 b 的值,直接返回假 (短路,捷径,-> 短路操作符)
- 例: a && b
- 逻辑或 ||
- 例: a || b
- a 和 b 全为假,返回假,否则返回真
- a 为真时,不再判断 b 的值,直接返回真 (短路,捷径,-> 短路操作符)
- 例: a || b
- 短路操作符的返回值:
和c语言不同,c语言的逻辑操作返回的布尔逻辑值;perl的短路操作符求职的不是简单地布尔逻辑,而是最后运算的那部分表达式的值;
#!/usr/bin/perl
#Code1
my $last_name = $last_name{$someone} || "no last name";
#如果哈希值不存在,即undef,返回默认值"no last name"
#如果哈希值存在且为0,即$someone对应的值为0,返回默认值"no last name"
#如果哈希值存为"sue",即$someone对应的值为sue,返回值"sue"
#Code2
#假如我们希望只检查$last_name是否有定义,而不关心其值是否为0,将以上程序改为:
my $last_name = (defined $last_name{$someone}) ? $last_name{$someone} : "no last name";
#如果哈希值不存在,即undef,返回默认值"no last name"
#如果哈希值存在且为0,即$someone对应的值为0,返回值0
#如果哈希值存为"sue",即$someone对应的值为sue,返回值"sue"
#Code3
#简单的功能却需要很复杂的语句,因此,perl定义了新的操作符: 定义或 // (只关心是否定义,不关心其值是否为零)
my $last_name = $last_name{$someone} // "no last name";
#如果哈希值不存在,即undef,返回默认值"no last name"
#如果哈希值存在且为0,即$someone对应的值为0,返回值0
#如果哈希值存为"sue",即$someone对应的值为sue,返回值"sue"
4.3 使用部分求值的控制结构
- 前面介绍的4个操作符: && || ?: // 有一个共同的特征:先判断左边表达式的值,然后决定是否执行右边的表达式。
- 根据左边的表达式,判断是否执行右边的表达式可以使他们跳过一些语句的执行;
- 所有能跳过语句执行的操作符都可以算作是控制结构。
#!/usr/bim/perl
($m < $n) && ($m = $n); # 如果$m >= $n,不执行右边操作
# 如果$m < $n,计算右边操作,$m = $n
#功能相同的其他写法
if ($m < $n) { $m = $n }
$m = $n unless $m >= $n;
$m = $n if $m < $n;
#compare
($m < $n) && ($m = $n); # -> if ($m < $n) { $m = $n }
($m < $n) || ($m = $n); # -> $m = $n unless $m < $n;
逻辑与和逻辑或还可以写作其他形式:
- && -> and (标点 -> 单词操作符,优先级降低)
- || -> or (标点 -> 单词操作符,优先级降低)
#!/usr/bin/perl
($m < $n) && ($m = $n); # -> if ($m < $n) { $m = $n }
$m < $n and $m = $n;
#1. and优先级低,可以省略一些括号(使用较少,不建议)
#2. 建议使用if形式,语义更加明确
(open FILE,'<',$filename) || (die "Can't open '$filename': $!"); # (open FILE,'<',$filename) unless (die "Can't open '$filename': $!");
open FILE,'<',$filename
or die "Can't open '$filename': $!";
#1. or优先级低,可以省略一部分括号(使用较多,建议)
#2. 如果打开句柄成功,不会执行die函数
#3. 如果打开句柄失败,执行die函数退出程序