Пятница, 24.11.2017, 10:26
Приветствую Вас Гость | RSS
Главная | Лекции | Регистрация | Вход
Меню сайта
Форма входа
Логин:
Пароль:
Категории раздела
Лекция [24]
Мини-чат
100
Поиск
Наш опрос
Оцените мой сайт
Всего ответов: 2
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Программирование Perl
    Главная » Статьи » Лекция » Лекция

    Лекция 4.1: Управляющие структуры

    Термы и простые предложения

    Минимальная синтаксическая единица языка программирования называется термомТерм (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 и использоваться переходы lastnext и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. Этот оператор имеет три разновидности.

    1. Переход к выполнению предложения, перед которым стоит метка:
      goto МЕТКА;
    2. Переход к метке, имя которой получено в результате вычисления выражения:
      goto выражение;
    3. Замена вызова указанной подпрограммы на подпрограмму, выполняющуюся в данный момент (применяется загрузчикамимодулей Perl):
      goto &подпрограмма;

    Оператор goto заслуженно порицается теоретиками и практиками программирования, поскольку он сильно запутывает логику выполнения программы. Так что правилами хорошего стиля программирования рекомендуется использовать его только при крайней необходимости. Хотя goto и можно применить для выхода из цикла, но для этого лучше воспользоваться операторомlast.

    Категория: Лекция | Добавил: mazay (06.02.2014)
    Просмотров: 50 | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Создать бесплатный сайт с uCozCopyright MyCorp © 2017