Иллюстрированный самоучитель по Perl

Команды управления циклом

Команда next, употребленная совместно с идентификатором метки прерывает выполнение цикла, в теле которого она находится, и начинает новую итерацию цикла с указанной меткой, выполнив предварительно его блок continue, если таковой имеется (пример 5.15).

#! peri – w
$out = – 0;
OUT: while ($out < 2) {
print "Начало внешнего цикла\п";
for($in=0; $in<=2; $in++) {
print "\$out: $out\t\$in: $in\n"; next OUT if $in =1; }
print "\$out: $out\n"; # Никогда не выполняется! } continue {
print "Блок continue внешнего цикла\п"; $out++; }

Вывод этой программы будет следующим:

Начало внешнего цикла
$out: 0 $in: 0
$out: 0 $in: 1
Блок continue внешнего цикла
Начало внешнего цикла
$out: I $in: 0
$out: I $in: 1
Блок continue внешнего цикла

Обратите внимание, что количество итераций внутреннего цикла for равно двум, так как на второй его итерации выполняется команда next OUT, прекращающая его выполнение и инициализирующая выполнение очередной итерации внешнего цикла OUT. Оператор печати этого цикла пропускается, выполняется блок операторов continue, проверяется условие и если оно истинно, то тело цикла выполняется. Таким образом, оператор печати внешнего цикла OUT не выполняется ни одного раза, что подтверждается приведенным выводом из программы примера 5.15.

Команда redo

Команда redo повторно выполняет операторы тела цикла, не инициализируя следующую итерацию. Это означает, что ни выражение изменения цикла for, ни операторы блока continue, если он присутствует, ни выражение условия не вычисляются. Операторы тела цикла, расположенные за оператором redo, пропускаются и снова начинается выполнение тела цикла со значениями переменных, которые они имели перед выполнением этой передачи управления. Программа примера 5.16 демонстрирует использование команды redo.

I! peri – w $notempty= 0;
$total = 0;
for (;;) { tt Бесконечный цикл
$line=<STDIN>; # Ввод строки
chop($line);
last if $line eq "END"; # Выход из цикла
++$total;
redo if $line eq ""; # Возврат на чтение строки
++$notempty; }
print "Всего прочитано строк: $total\nM3 них не пустых: $notempty\n";

Эта программа в бесконечном цикле ожидает ввода пользователем на клавиатуре строки данных и в переменной $ total подсчитывает количество введенных строк. В переменной $notempty вычисляется количество введенных не пустых строк. Если введена пустая строка, то команда redo начинает повторное выполнение операторов тела цикла, не увеличивая на единицу переменную $notempty. Для завершения бесконечного цикла следует ввести строку END. В этом случае выполняется команда last.

Функция chop используется для удаления из введенной пользователем строки символа перехода на новую строку "\п", поэтому в программе она сравнивается со строками без завершающего символа перехода на новую строку (сравни с примером 5.7).

Если команда redo используется с идентификатором метки, то ее действие аналогично действию команды next с той лишь разницей, что она просто передает управление на первый оператор тела цикла с указанной меткой, не инициируя следующей итерации и не вычисляя операторов блока continue. В качестве иллюстрации такого использования команды redo перепишем программу примера 5.16 следующим образом:

#! peri – w $notempty = 0; $total = 0; OUT: while (1) {
print "Введи строки\п"; # Сюда передает управление команда redo OUT; for {;;) {
$line=<STDIN>;
chop($line);
last OUT if-$line eq "END"; I Выход из всех циклов
++$total;
redo OUT if $line eq "";
++$notempty; } } print "Всего прочитано строк: $tptal\nH3 них не пустых: $notempty\n";

В примере 5.17 мы ввели внешний бесконечный цикл OUT и изменили команды redo и last, добавив к ним метку на внешний цикл. Теперь в случае, если пользователь вводит пустую строку, команда redo OUT передает управление на первый оператор внешнего цикла, и программа печатает приглашение ввести строки.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.