Операторы ветвления

При реализации алгоритмов всегда возникают ситуации, когда какой-либо оператор или группу операторов надо выполнить в случае возникновения определенных условий, тогда как другую группу при этих же условиях вообще не следует выполнять. В языке Perl для организации подобного ветвления в программе предусмотрены операторы if, которые мы и будем называть операторами ветвления,
Отличительной особенностью всех этих операторов является то, что в них вычисляется некоторое выражение, называемое условием, и в зависимости от его истинности или ложности выполняются или не выполняются операторы некоторого блока. Это означает, что выражения условия во всех операторах ветвления вычисляются в булевом контексте.
Самая простейшая форма оператора ветвления if представлена следующей синтаксической конструкцией:
if (ВЫРАЖЕНИЕ) БЛОК
Ее семантика такова — если ВЫРАЖЕНИЕ истинно, то выполняются операторы блока БЛОК, в противном случае он просто пропускается, например:
if ( $var == "print" ) { 
  print "Переменная \$text = $text";
}
ВНИМАНИЕ Еще раз напомним читателю тот факт, что все составные операторы определяются в терминах блоков, задаваемых с помощью фигурных скобок, поэтому даже если в блоке содержится один оператор, он должен быть заключен в фигурные скобки. Такой синтаксис составных операторов Perl может оказаться не совсем привычным для программистов на языке С, в котором фигурные скобки в случае одного оператора в блоке не обязательны.
Обычно выражение условия представляет собой сложное выражение, составленное из операций отношения, связанных логическими операциями. Однако в Perl в качестве выражения-условия операторов if можно использовать любое выражение, а не только булево, возвращающее «истину» или «ложь». Результат вычисления такого «выражения-условия» в этих операторах просто интерпретируется в булевом контексте по следующей схеме: если вычисленное значение равно 0, "0" или пустой строке "", то оно трактуется как «ложь», иначе — «истина».
В связи со сказанным мы можем написать следующий оператор, который напечатает введенную пользователем строку, если только она не является пустой или состоящей из одного нуля (только строка "0" трактуется как «ложь»):
if (substr $var = <>, 0, length($var)-l) {
  print "Ввели $var"; 
}
Интерес здесь представляет выражение-условие. Функция substr( ) выделяет из первого строкового параметра, начиная с позиции, определяемой вторым параметром, подстроку длины, определяемой третьим параметром. Первым параметром этой функции в нашем случае является введенная пользователем строка. Из нее, начиная с самого первого символа, выделяется подстрока на единицу меньшей длины, чем ввел пользователь. Такие действия необходимы для исключения из переменной $var символа перехода на новую строку, который автоматически включается в нее при вводе со стандартного устройства ввода (операция <>), когда пользователь завершает ввод нажатием клавиши Enter, Результатом выполнения указанной операции будет именно та последовательность символов, которую вводил пользователь, хотя в самой переменной $var символ перехода на новую строку будет сохранен. В этом можно убедиться, добавив в блок еще один оператор печати. Его вывод будет осуществляться уже на новой строке после вывода предыдущего оператора print.
Вторая форма оператора if используется, когда необходимо выполнить одну группу операторов (БЛОК1) в случае истинности некоторого выражения (ВЫРАЖЕНИЕ), а в случае его ложности — другую группу операторов (БЛОК2):
if (ВЫРАЖЕНИЕ) БЛОК1 else БЛОК2
По существу, первая форма оператора if эквивалентна второй форме, если БЛОК2 не содержит ни одного оператора.
Иногда приходится делать выбор на основе проверки нескольких различных условий. Для подобных цепочек ветвлений существует специальная форма оператора if, реализующая множественные проверки:
if (ВЫРАЖЕНИЕ1) БЛОК1 [elsif (ВЫРАЖЕНИЕ2) БЛОК2]  ...  [else БЛОКn]
ПРИМЕЧАНИЕ Квадратные скобки используются исключительно для обозначения необязательности конструкции, а многоточие показывает, что заключенная в квадратные скобки стоящая перед ними конструкция может повторяться многократно. Таким образом, квадратные скобки не являются частью синтаксиса многовариантного оператора if.
Семантика этого оператора такова. Выполняются операторы блока БЛОК1, если истинно ВЫРАЖЕНИЕ1. Если оно ложно, то выполняются операторы блока БЛОК2 в случае истинности выражения ВЫРАЖЕНИЕ2 из конструкции elseif. Если и оно ложно, то проверяется выражение ВЫРАЖЕНИЕЗ из следующей конструкции elseif и т. д. Если ни одно из выражений-условий оператора if не истинно, то в случае наличия конструкции el se выполняются операторы ее блока, иначе выполняется следующий после оператора if оператор программы. Например, при выполнении приводимого ниже оператора многовариантного ветвления if:
if($var < 0) {                            # ВЫРАЖЕНИЕ1
  print "Переменная отрицательна";        # БЛОК1
} elsif ( $var == 0) {                    # ВЫРАЖЕНИЕ2
       print "Переменная равна нулю";     # БЛОК2 
} else { print "Переменная положительна"; # БЛОКЗ }
сначала проверяется условие отрицательности переменной $var. Если значение переменной строго меньше нуля (ВЫРАЖЕНИЕ1), то печатается сообщение из блока БЛОК1 и оператор завершает свою работу. Если значение переменной не меньше нуля, то далее оно проверяется на равенство (ВЫРАЖЕНИЕ2), и в случае истинности выполняется оператор печати из блока операторов elsif (БЛОК2). Если проверка на равенство нулю дала ложный результат, то выполняется оператор печати из блока else (БЛОКЗ).
ПРИМЕЧАНИЕ Ключевое слово else вместе со своим блоком операторов может быть опущено.
Следует запомнить, что во многовариантном операторе if может быть сколько угодно блоков elseif, но только один или же вообще ни одного блока else.
Относительно многовариантного оператора ветвления if и оператора с блоком else языка Perl следует заметить, что, так как они определяются в терминах блоков, не возникает никакой двусмысленности при определении, какие операторы какой части оператора условия принадлежат. Блоки всегда дают нам однозначное решение.
ВНИМАНИЕ При работе с операторами ветвления важно помнить, что только один блок операторов будет выполнен – тот, для которого истинно соответствующее выражение условия.
В Perl кроме операторов ветвления if также определены операторы ветвления, в которых вместо ключевого слова if используется ключевое слово unless. В этом случае проверка выражения условия осуществляется на его ложность. Например, последний оператор if можно записать и так:
unless ($var >= 0) {                     # ВЫРАЖЕНИЕ1
  print "Переменная отрицательна";       # БЛОК1
} elsif ($var == 0) {                    # ВЫРАЖЕНИЕ2
    print "Переменная равна нулю";       # БЛОК2 
  } else {
        print "Переменная положительна"; # БЛОК3
    }
При этом нам пришлось заменить ВЫРАЖЕНИЕ1 на противоположное по смыслу. Подобные «замены» в выражениях условия операторов ветвления характерны при использовании вместо ключевого слова if ключевого слова unless.
ПРИМЕЧАНИЕ Все операторы могут быть вложенными, то есть в любом их блоке можно свободно использовать другие операторы ветвления.
Завершая разговор об операторах ветвления if/unless, следует сказать об использовании в них локальных лексических переменных. Если в выражении-условии объявить лексическую переменную, то она также будет видна во всех блоках оператора ветвления, включая блоки if, все elseif и else. Вне оператора ветвления, естественно, такая переменная недоступна. Например, следующий оператор if проверяет введенную пользователем строку на равенство yes или nо, сохраняя ее в локальной переменной $answer, которая доступна во всех блоках составного оператора:
if ((my $answer = <STDIN>) =~ /^yes$/i) {
  chomp $answer
  print "'$answer' равно 'yes'";
} elsif ($answer =~ /^no$/i) {
    chomp $answer;
    print "'$answer'  равно 'nо'"; }
  else {
    die "'$answer' не равно ни 'yes', ни'nо'";
  }
ПРИМЕЧАНИЕ Регулярные выражения использованного оператора if определяют, что введенная пользователем строка должна состоять либо из единственного слова yes, либо из единственного слова no, которое должно начинаться с первой позиции, на что указывает метасимвол ^, и «простираться» до конца строки, на что указывает метасимвол $. Флаг i в конце регулярного выражения определяет, что поиск соответствующего слова происходит без учета регистра, то есть заданным регулярным выражениям будут соответствовать слова yes или no, набранные как прописными, так и строчными буквами, а также в смешанном варианте.

Следующая страница Содержание главы


Реклама