Шаг 16.
Цикл for

    На этом шаге мы рассмотрим использование цикла for.

    При выполнении циклов while и until заранее неизвестно, сколько итераций необходимо выполнить. Их количество зависит от многих факторов: значений переменных в выражении условия до начала выполнения цикла, их изменение в теле цикла,от вида самого условия и т. п. Но иногда в программе необходимо выполнить заранее известное количество повторений определенной группы операторов. Например, прочитать из файла 5 строк и видоизменить их по определенным правилам. Конечно, можно такую задачу запрограммировать операторами цикла while и until, но это может быть неоптимальноо. Для решения подобных задач с заранее известным числом повторений язык Perl предлагает специальную конструкцию цикла — цикл for:

  [МЕТКА:] for (<ВЫРАЖЕНИЕ1>; <ВЫРАЖЕНИЕ2>; <ВЫРАЖЕНИЕ3>) 
<БЛОК>

ВЫРАЖЕНИЕ1 используется для установки начальных значений переменных, управляющих циклом, поэтому его называют инициализирующим выражением. Обычно это одна или несколько операций присваивания, разделенных запятыми. ВЫРАЖЕНИЕ2 определяет условие, при котором будут повторяться итерации цикла. Оно, как и выражение-условие цикла while, должно быть истинным, чтобы началась следующая итерация. Как только это выражение становится ложным, цикл for прекращает выполняться и передает управление следующему за ним в программе оператору. ВЫРАЖЕНИЕ3 отвечает за увеличение/уменьшение значений переменных цикла после завершения очередной итерации. Обычно оно представляет собой список выражений с побочным эффектом или список операций присваивания переменным цикла новых значений. Его иногда называют изменяющим выражением.

    Алгоритм выполнения цикла for следующий:

  1. Вычисляется инициализирующее выражение (ВЫРАЖЕНИЕ1).
  2. Вычисляется выражение условия (ВЫРАЖЕНИЕ2). Если оно истинно, то выполняются операторы блока БЛОК, иначе цикл завершает свое выполнение.
  3. После выполнения очередной итерации вычисляется выражение увеличения/уменьшения (ВЫРАЖЕНИЕЗ) и повторяется пункт 2.

    Все три выражения цикла for являются необязательными и могут быть опущены, но соответствующие разделители ";" должны быть оставлены. Если опущено выражение условия, то по умолчанию оно принимается равным Истина. Это позволяет организовать бесконечный цикл:

   for   (;;)    {
         .    .   .
   }
Выход из такого цикла осуществляется командами управления, о которых речь пойдет в следующих шагах.

    Цикл for позволяет использовать несколько переменных для управления работой цикла. В этом случае в инициализирующем и изменяющем выражениях используется операция запятая. Например, если мы хотим создать хеш, в котором ключам, представляющим цифры от 1 до 9, соответствуют значения этих же цифр в обратном порядке от 9 до 1, то эту задачу можно решить с помощью цикла for с двумя переменными цикла:

      for   ($j = 1, $k = 9; $k>0; $j++, $k-- )    {
           $hash{$j}   =  $k; }

    Цикл for достаточно гибкая конструкция, которую можно использовать не только для реализации цикла с заранее заданным числом итераций. Он позволяет в инициализирующем и изменяющем выражениях использовать вызовы встроенных и пользовательских функций, а не только определять и изменять переменные цикла. Основное — чтобы изменялось выражение условия завершения цикла. Следующий пример демонстрирует именно такое использование цикла for.

for (print "Введите данные, для завершения ввода нажмите клавишу Enter\n"; 
    <STDIN>;
    print  "Введите данные, для завершения ввода нажмите клавишу Enter\n") 
{
        last if $_ eq "\n"; 
        print "Ввели строку:   $_";
} 
Текст этого примера можно взять здесь.

    В этом примере пользователь вводит в цикле строки данных. Перед вводом новой строки отображается подсказка с помощью функции print(), которая определена в изменяющем выражении цикла. Выражение условия представляет операцию ввода из файла стандартного ввода <STDIN>. Так как это выражение вычисляется всякий раз, когда цикл переходит на очередную итерацию, то на каждом шаге цикла программа будет ожидать ввода с клавиатуры. Выход из цикла осуществляется командой last, вызываемой в случае ввода пользователем пустой строки. Введенные данные сохраняются во встроенной переменной $_, причем в ней сохраняется и символ перехода на новую строку, являющийся признаком завершения операции ввода данных. Поэтому при вводе пустой строки на самом деле в переменной $_ хранится управляющая последовательность "\n", с которой и осуществляется сравнение для реализации выхода из цикла.

    Приведем еще один пример использования цикла for: определение максимального элемента в массиве.

@array = (1, -6, 9, 18, 0, -10);
$max = $array[0];       # Присваиваем переменной значение 1 элемента.
for ($i = 1; $i<=$#array; $i++)   {
   $max = $array[$i] if $array[$i] > $max; } # Если элемент массива 
 # больше значения переменной $max, то переменная $max становится 
 # равной значению этого элемента. Обратите внимание, что 
 # выражение выполняется справа налево.
}
print “Максимальный элемент \$max = $max\n”;  
Текст этого примера можно взять здесь.

    В следующем примере приведен текст программы, читающей 3 строки файла err.err. Операция чтения из файла задается в инициализирующем и изменяющем выражении вместе с определением и изменением переменной цикла $i.

  open (FF, "err.err") or die "Ошибка открытия файла";
  for ($line=<FF>, $count = 1; $count <=3; $line=<FF>, $count++)
  {
    print "Строка $count:\n $line\n"; 
  } 
  close(FILE);
Текст этого примера можно взять здесь.

    На следующем шаге мы продолжим изучение циклических конструкций.




Предыдущий шаг Содержание Следующий шаг