1.6.2 循环结构 BACKWARDFORWARD


Perl有四种主要的循环语句类型: while, until, for和foreach。这些语句允许Perl程序以不同的值重复执行同一段代码。

while和until语句

while和until语句函数以循环的形式类似于if和unless语句。首先,语句的条件部分被检测。如果条件满足(对于while条件为真, 或对于until条件为假), 执行语句的block。

while ($tickets_sold < 10000)

  $availabe = 10000 - $tickets_sold;

  print "$available tickets are available.

How many would you like: ";

  $purchase =<STDIN>;

  chomp($purchase);

  $tickets_sold += $purchase;

注意如果条件永不满足, 永不进入循环。例如,我们已卖了10000张票, 我们可能有下行程序是这样的:

print "This show is sold out, please come back later.";

在前面班级的例子中, 4行是:

while ($line = ) 这是把下一行给变量$line, 象我们前面解释的一样, 返回$line的值, 以便while语句的条件能计算$line的真值。你可能想知道Perl是否在空行得到一个"假的相反"时, 跳出循环。这个答案是不跳出。如果你想想我们所说的,原因是清楚的。行输入操作符在字符串末尾给出换行符,所以空行有一个“"值。而你知道""不是假值。所以条件为真,既使在空行循环仍继续。

另一方面,当我们最后到达文件的尾部时,行输入操作符返回无定义,其总是假。也就是我们所想的,循环结束。在Perl中, 没有必要要求一个显式的检测函数eof, 因为输入操作符已设计得在条件上下文中很好地工作。

事实上,在条件上下文中,几乎每件事都设计得很好。例如,在一个标量上下文中,一个数组返回它的长度。所以你经常能看到这样:

while (@ARGV)

  process(shift @ARGV);

当@ARGV的长度为零时, 循环自动地退出。

for语句

另一个循环语句是for循环。一个for循环恰巧象while循环一样运行, 但有很多不同(尽管C编程者发现很熟悉)。

for ($sold = 0; $sold < 10000; $sold += $purchase)

  $available = 10000 - $sold;

  print "$available tickets are available.

How many would you like: ";

$purchase = <STDIN>;

  chomp($purchase);

for循环在循环的括号内有三个表达式: 一个表达式设置循环变量的初始状态, 一个检测循环变量的条件, 一个修改循环变量状态的表达式。当循环开始时,设置初始状态并检测条件是否为真。如果条件为真,执行block。当block完成时, 修改表达式, 再检测条件是否为真, 如果为真, 用新值再运行block。只要条件为真,就执行block和修改表达式。

foreach语句

Perl的主要循环语句的最后一个是foreach语句。foreach语句对已知标量集(比如一个数组)的每个标量执行同一段程序:

foreach $user (@users)

  if (-f "$home$user/.nexrc")

   print "$user is cool ... they use a perl-aware vi!\n";

foreach语句中, 括号中的表达式用于产生一个表。然后表中的每个元素依次赋给循环变量,并对每个元素执行一次block。注意循环变量成为对元素本身的一个引用,而不是元素的一个拷贝。因此,修改循环变量将修改原来的数组。

你会发现在典型的Perl程序中foreach循环比for循环多, 因为在Perl中很容易产生foreach需要用于循环的表。一个经常看到的是:对hash表中已排序的关键字进行循环:

foreach $key (sort keys %hash)

事实上, 班级例子的9行正是这样做的。

跳转语句:next和last

next和last操作符允许你修改循环的流程。对于特殊情况,这不是非一般的;当遇到这种情况时,你可以跳过,或可以退出。例如,如果你正处理有关UNIX的文件, 你可以跳过系统命令(象root或lp)。next操作符允许你跳到当前循环的末尾, 开始下一次循环。last操作符允许你跳到block的末尾, 好象检测条件为假一样。这是有用的,例如,你正在寻找一个特殊词并且一找到就退出。

foreach $user (@users)

  if ($user eq "root" or $user eq "lp")

    next;

  if ($user eq "special")

    print "Found the special account.";

    #做一些处理

    last;

通过标号循环并指定你想跳转到哪一个循环, 跳出多级循环是可能的。和修饰符(另一种条件形式, 我们没有谈到过), 如果你正好认为英语是易读的, 那么这个就是为很易读的循环退出而设计的:

LINE: while ($line = <ARTICLE>

 last LINE if $line eq "";  #停在第一个空行

 next LINE if /^#/;  #跳过说明

 #your ad here

你可能说,"等等, 在一对斜线内的^#是什么 ? 并不象英语。" 你是对的。这是包含一个规则表达式的一种匹配语句。这也是下一节的内容。上面讲Perl是一种文本处理语言, 而规则表达式是文本处理的核心。


Copyright: NPACT BACKWARDFORWARD