SOURCE HTML: http://socvista.com/bbs/redirect.php?fid=71&tid=929&goto=nextnewset
第10章 控制结构
08:11 unless
== unless 控制结构 (不重要,罗嗦)
unless 是 if 的相反结构。if是条件满足的时候执行。unless 是条件不满足的时候执行。
if (! condition) {}
等价于
unless (condition) {}
此外,unless也可以和else 连用。他的含义和if也是刚好相反。
08:16 until
== until 控制结构 (不重要)
until是while的相反结构。while是判断条件true的时候执行,until是判断条件false的时候执行。
until ($j > $i) {
$j *= 2;
}
08:20 expression modifiers
== 省略书写的捷径——expression modifiers
采用if / while / unless / foreach / until
等等控制结构书写代码的时候,常常伴随着大括号以及其他的辅助符号。在Perl程序员的世界里,都是一群懒人,因此,省略书写成为一种主流。看看下面的例
子,就明白什么是 expression modifier 了。
print "something" if $n < 0;
&error("error") unless &valid($input);
$i *= 2 until $i > $j;
print "something", ($n += 2) while $n < 10;
&greet($_) foreach @person;
不过为了好看一点,也有人将条件修改符换行后书写。
print "something"
foreach @tasks;
注意分号在第二行,否则是错的。
08:41 Naked block
== 创建一个独立的Block
独立的Block,形如下面:
{
语句1;
语句2;
语句3;
}
就是把正常的代码用花括号覆盖。
为什么要这么做呢?理由是为了使用局部变量。我们说过my变量只在一个block内有效。因此有时候为了使用并限制局部变量,就用花括号来规定范围。不过这种用途不是很多。
08:57 Elsif 语句
== 处理多种可能的方法:elsif 语句
看例子就明白,这个语句还是有些用场的。
if () {
} elsif () {
} elsif () {
} elsif () {
}
要注意,是elsif,那个e字母是省略掉的。
09:03 Autoincrement & Autodecrement
== 自动递增与递减符号
预递增:先将变量取值递增,然后将递增后的值用于运算。因为是预递增,所有++符号放在变量前。
my $n = ++$m;
后递增:先将变量取值值用于运算,然后将变量递增。因为是后递增,所有++符号放在变量后。
my $n = $m++;
关于递减的两种用法雷同。不再赘述。
09:11 for控制结构
== for 循环
for结构和C语言一样。
for (initialization; test; increment) {
body;
body;
}
比如,
for ($i = 10; $i >= 1; $i--) {
print "$i";
}
for的三个控制部分形式可以各种各样,比如
for ($_ = "bedrock"; s/(.)//;) {
print "removed $1\n";
}
上面的例子每一次都从$_里面删除一个字符,然后判断替换操作是否成功,直到最后一次,因为字串变空,替换不成功,for循环才告结束。
还可以构造无限循环,比如,
for (;;) {}
上述语句,等价于
while (1) {}
09:31 Loop Control
== 循环的控制之 last
这个相当于C语言中的break,使程序跳出loop,进入下面的代码。看例子。
while (<STDIN>) {
if (/__END__/) {last;
} elsif (/fred/) {
print;
}
}
注意,如果有多层嵌套循环,则last只会跳出最近的一层循环。
所谓的循环有5种,分别是 for / foreach / while / until / naked-block。
09:55 Loop Control
== 循环控制之next
等同于C语言中的continue。其作用是从当前这一轮loop中出来直接进入下一轮loop。见例子。
while (<>) {
foreach (split) { # 将$_根据空格分割成单词,然后逐一处理
$total++;
next if /\W/; # 如果碰到奇怪的字符则退出当前loop
$valid++;
$count{$_}++; # 在hash表中寻找相关的key并将其value递增
}
}
09:56 Loop control
== 循环控制之 redo
redo是C语言里面没有的特性。他会要求程序返回到当前loop的起始处开始执行。和next的不同之处在于,它不要求程序进入下一个loop而只是重复当前的loop。看例子。
foreach (@words) {
## redo 后会从这儿开始执行 ##
print "type the word '$_': ";
chomp(my $try = <STDIN>);
if ($try ne $_) {
print "sorry - that's not right. \n";
$errors++;
redo; # 调回loop的起始处
}
}
大家仔细看的话,这是一个练习打字的程序。
这个loop控制也是很有用的。
10:20 Loop control
== 循环控制之用标签标识block
每个block都可以用标签进行标识,以方便定位。比如前面提到的last / next / redo 一般只对最内层的 block 进行操作。但是使用了 label 之后,就可以和嵌套中的任意 block 发生关系。比如
LINE: while (<>) {
foreach (split) {
last LINE if /__END__/; # 跳出LINE loop
.......
}
}
注意:label一般都用大写字母。以示和一般关键字的区别。
10:36 Logical operators
== 逻辑操作符
这些操作符号和C语言一样。
1. &&
2. ||
3. condition ? clause-a : clause-b;
另外还有一种 partial-evaluation operator,部分运算符。什么意思呢?看例子
($m > 10) || print "why is it not greater?\n";
当$m > 10的时候什么也不发生,反之则执行 print。也就是要使这个表达式为逻辑1即可。
但是这个功能可以用if实现,这种部分运算的表达方式反而很不直观。
所以,虽然有这个功能,我也不建议大家学,我自己也就当是看个热闹。