Термы и простые предложенияМинимальная синтаксическая единица языка программирования называется термом. Терм (term) - это все то, что может служитьоперандом в выражении, например, литерал или переменная. Выражение напоминает неоконченную фразу в естественном языке. Чтобы выражение стало законченным предложением (statement, называемым также утверждением), нужно после него поставить символ ";" (точка с запятой). Другими словами, простое предложение - это выражение, вычисляемое ради его побочного эффекта. Кроме предложений, в программе на Perl могут присутствовать объявления переменных и подпрограмм, которые будут рассмотрены позднее. Приведем примеры простых предложений: $count = 0; # присваивание значения переменной
$count++; # изменение значения операнда
$result = 'Итого=' . $count . "\n"; # подготовка к печати
1; # литерал - минимальное, но корректное предложение Последнее предложение, кажущееся бессмысленным, применяется в последней строке модулей для возврата "истинного" значения при успешной загрузке модуля. О модулях будет подробно рассказано в лекции 13. УсловияКак известно, условные предложения определяют выполнение тех или иных действий в программе в зависимости от проверки заданного условия. В Perl условная конструкция (или оператор if ), проверяющая истинность одного условия, в самом простом виде записывается так: if (условие) { # проверка истинности условия
# действия, выполняемые,
# если условие истинно
}
# продолжение программы Обратите внимание, что после условного выражения, обязательно заключенного в круглые скобки, непременно должен стоять блок. Например, так можно вывести на печать значение переменной при условии, что оно - нечетное: if ($count % 2 == 1) { # остаток от деления на 2 равен 1
print $count;
} Другая общеизвестная форма условного предложения содержит блок, выполняемый при ложном условии, а именно: if (условие) { # проверка истинности условия
# действия, выполняемые,
# если условие истинно
} else {
# действия, выполняемые в противном случае
# (если условие ложно)
}
# продолжение программы В Perl имеется еще одна форма условного предложения, которая задает последовательную проверку нескольких условий, указанных в фразе if или elsif. Она выглядит следующим образом: if (условие 1) { # проверка истинности 1-го условия
# действия, выполняемые,
# если условие 1 истинно
} elsif (условие 2) { # проверка истинности 2-го условия
# действия, выполняемые,
# если условие 2 истинно
# ... здесь могут быть еще фразы elsif ...
} elsif (условие N) { # проверка истинности N-го условия
# действия, выполняемые,
# если условие N истинно
} else {
# действия, выполняемые,
# если все условия ложны
}
# продолжение программы При этом выполнится один из блоков действий: соответствующий первому истинному условию или указанный за фразой else. Фраза else может отсутствовать, тогда при всех ложных условиях не делается ничего. Форма условного предложения сelsif заменяет отсутствующий в Perl оператор выбора (такой как do-case или switch ). Иногда требуется подчеркнуть, что, наоборот, ложность условия становится причиной выполнения каких-либо действий. Для этого в Perl есть еще одна разновидность условного предложения, которая записывается с помощью ключевого слова unless: unless (условие) { # проверка ложности условия
# действия, выполняемые,
# если условие ложно
} else {
# действия, выполняемые
# в противном случае
}
# продолжение программы Здесь фраза else также может отсутствовать, если при истинности условия не требуется выполнять никаких действий. Как уже известно из предыдущей лекции, выражать условное выполнение действия можно и другим, очень популярным в Perlспособом: с помощью логических операций. Так, например, можно напечатать результат, если первое выражение будет истинным: ($count % 2 == 1) and print $count; Условное выполнение действия можно также задавать с помощью модификаторов, о которых речь пойдет далее в этой лекции. ЦиклыКак известно, циклом называется управляющая конструкция для повторения действий в программе, а однократное выполнение предложений в цикле называется итерацией. В Perl существует множество различных способов задать циклическую обработку данных. Один из них - это операторы управления циклом. Если требуется повторение действий в зависимости от истинностиусловия, можно воспользоваться циклом while (называемый также циклом с предусловием), в котором каждый раз перед выполнением цикла проверяется условие продолжения: если оно истинно, то блок тела цикла повторяется, иначе цикл заканчивается и выполняется следующее предложение программы. while (условие) { # проверка истинности условия продолжения
# действия, выполняемые,
# пока условие истинно
}
# продолжение программы Например, можно воспользоваться таким циклом while для вывода на системную консоль десяти случайных чисел от 0 до 1, сгенерированных встроенной функцией rand: $i = 0;
while ($i < 10) { # повторять, пока счетчик не достиг 10
print "\n", rand; # вывести с новой строки случайное число
$i++; # увеличить счетчик повторений
} Иногда удобнее для управления циклом задавать условие окончания цикла. В этом случае применяется цикл until, в котором каждый раз перед выполнением тела цикла проверяется условие окончания повторений: если оно истинно, цикл заканчивается и выполняется следующее предложение программы, а если условие ложно, то блок тела цикла выполняется еще раз. until (условие) { # проверка истинности условия окончания
# действия, выполняемые,
# пока условие ложно
}
# продолжение программы Предыдущий пример вывода случайных чисел можно переписать с использованием цикла until: $i = 0;
until ($i == 10) { # закончить, когда счетчик достигнет 10
print "\n", rand; # вывести с новой строки случайное число
$i++; # увеличить счетчик повторений
} Другая управляющая конструкция - цикл for также применяется для повторения действий с проверкой условия продолжения. Но в нем предусмотрены два дополнительных выражения для управления циклом. Первое из них выполняется один раз перед выполнением цикла, и в нем обычно выполняются начальные действия, такие как инициализация переменных. Второе выражениевыполняется каждый раз после выполнения тела цикла и перед проверкой условия продолжения работы цикла. Структура этогоцикла выглядит так: for (первое выражение; условие; второе выражение) {
# действия, выполняемые,
# пока условие истинно
}
# продолжение программы В заголовке цикла могут отсутствовать одно или оба выражения, а в случае отсутствия условия оно считается истинным. Однако при этом должны оставаться две точки с запятой, разделяющие выражения. Снова перепишем приведенный выше пример, на этот раз используя цикл for: for ($i=0; $i<10; $i++) { # повторить 10 раз, увеличивая $i
print "\n", rand; # вывести с новой строки случайное число
} Еще один тип цикла предназначен для перебора всех элементов списка, для чего каждый его элемент последовательно помещается в указанную переменную. Это цикл foreach: foreach переменная (список) { #
# работа с переменной, содержащей
# текущий элемент обрабатываемого списка
} Примеры использования цикла foreach будут приведены в лекции 5, посвященной спискам. В ней будет рассмотрено еще несколько конструкций, также выполняющих повторение действий. Управление циклами и переходыВ Perl есть несколько предложений для управления выполнением программы с помощью перехода в указанную точку программы. Обычно это требуется при работе с циклами. Когда при работе цикла требуется досрочно закончить его выполнение при наступлении какого-то события, то для этого можно воспользоваться оператором last (аналог оператора break в языке C), который прерывает выполнение цикла и переходит к выполнению предложения, следующего за циклом. Например, напечатать 10 случайных чисел от 0 до 0,5 можно так: $i = 0;
while (1) { # безусловно входим в цикл
$random = rand; # получаем случайное число
if ($i == 10) { # по достижении счетчика 10
last; # ПРЕРЫВАЕМ выполнение цикла
}
if ($random < 0.5) { # числа меньше 0.5
print "\n", $random; # выводим на консоль
$i++; # и увеличиваем счетчик повторений
}
}
# сюда произойдет переход по last Оператор next (аналог оператора continue в языке C) применяется, когда требуется пропустить выполнение оставшихся предложений в теле цикла и перейти к следующей итерации, начав с проверки условия в заголовке цикла. Вот так можно изменить последний пример, применив next: $i = 0;
while ($i < 10) { # пока счетчик не достигнет 10
$random = rand; # получаем случайное число
if ($random > 0.5) { # числа больше 0.5
next; # ПРОПУСКАЕМ действия в теле цикла
}
print "\n", $random; # выводим число на консоль
$i++; # и увеличиваем счетчик повторений
# сюда произойдет переход по next
} Оператор redo используется, когда нужно повторить выполнение предложений в теле цикла без проверки условия в заголовкецикла. Вот таким станет последний пример, если использовать redo: $i = 0;
while ($i < 10) { # пока счетчик не достигнет 10
# сюда произойдет переход по redo
$random = rand; # получаем случайное число
if ($random > 0.5) { # числа больше 0.5
redo; # СНОВА НАЧИНАЕМ действия в теле цикла
}
print "\n", $random; # выводим число на консоль
$i++; # и увеличиваем счетчик повторений
} Во всех рассмотренных циклах может присутствовать необязательный блок continue. В нем располагаются действия, которые нужно выполнить в конце цикла, в том числе при переходе к новой итерации по next. Действия в блоке continue не выполняются при переходах по last и redo. Это может показаться странным, но голый блок рассматривается в Perl как цикл, выполняющийся один раз. В таком блоке может присутствовать фраза continue и использоваться переходы last, next иredo. С учетом предложений управления циклом и блока continue циклическую структуру в общем виде можно изобразить так: # может быть заголовок цикла: while, until или for
{
# сюда происходит переход по redo
# действие 1, выполняемое в цикле
if (условие выхода) {
last; # выход из цикла
}
# действие 2, выполняемое в цикле
if (условие продолжения) {
next; # выполнение следующей итерации цикла
}
# действие 3, выполняемое в цикле
if (условие возобновления) {
redo; # выполнение тела цикла сначала
}
# действие N, выполняемое в цикле
# сюда происходит переход по next
} continue {
# действие, выполняемое после нормального завершения цикла
}
# сюда происходит переход по last Циклы могут быть вложены один в другой. Когда требуется прервать вложенный цикл, перед ним ставится метка. Метка - этоидентификатор, состоящий из латинских букв, знаков подчеркивания и цифр и начинающийся с буквы, после которого стоит знак двоеточия. Соблюдая хороший стиль программирования, следует записывать метки заглавными буквами. В операторе управленияциклом метка указывает, выполнение какого цикла нужно прервать: CYCLE_1:
while (условие продолжения цикла 1) {
CYCLE_2:
while (условие продолжения цикла 2) {
if (условие выхода из всех циклов) {
last CYCLE_1;
}
CYCLE3:
while (условие продолжения цикла 3) {
if (условия прерывания 2-го цикла) {
next CYCLE_2;
}
}
# сюда произойдет переход по next CYCLE_2
}
}
# сюда произойдет переход по last CYCLE_1 Метка может ставиться перед любым предложением. При помощи блока и операторов управления циклом с меткой можно имитировать управляющую структуру, подобную оператору switch в языке C. Например, так можно записать только одноприсваивание переменной $say в зависимости от условия: SWITCH: {
unless (defined $t) { # если $t не определено
$t = 25; redo SWITCH; # задать значение по умолчанию
}
if ($t < 10) { $say = 'холодно'; last SWITCH; }
if ($t < 18) { $say = 'прохладно'; last SWITCH; }
if ($t < 27) { $say = 'тепло'; last SWITCH; }
$say = 'жарко';
}
print "Сегодня $say\n"; В Perl имеется оператор перехода goto, в котором также используются метки. С его помощью можно перейти к выполнению помеченной конструкции в текущем или в вызывающем блоке. Но его нельзя применять для перехода в конструкцию, требующуюинициализации: подпрограмму или цикл for. Этот оператор имеет три разновидности. - Переход к выполнению предложения, перед которым стоит метка:
- Переход к метке, имя которой получено в результате вычисления выражения:
- Замена вызова указанной подпрограммы на подпрограмму, выполняющуюся в данный момент (применяется загрузчикамимодулей Perl):
Оператор goto заслуженно порицается теоретиками и практиками программирования, поскольку он сильно запутывает логику выполнения программы. Так что правилами хорошего стиля программирования рекомендуется использовать его только при крайней необходимости. Хотя goto и можно применить для выхода из цикла, но для этого лучше воспользоваться операторомlast.
|