Perl其他控制结构

版权声明:转载请说明出处! 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 的值,直接返回真 (短路,捷径,-> 短路操作符)
  • 短路操作符的返回值:
    和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函数退出程序

猜你喜欢

转载自blog.csdn.net/qq_39556143/article/details/85176184
今日推荐