Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Комплект Информатика / Курс лекций.doc
Скачиваний:
127
Добавлен:
22.05.2015
Размер:
4.8 Mб
Скачать

2 Управление циклами

Неоднократное использование инструкции или последовательности инструкций представляет собой важную алгоритмическую концепцию. Одним из методов организации такого повторения является итеративная структура, известная как цикл (loop); здесь последовательность инструкций, называемая телом цикла, многократно выполняется под контролем некоторого управляющего процесса. Типичный пример цикла можно найти в алгоритме последовательного поиска, представленном на рис. 4.6. Здесь инструкция while используется в целях управления повторным выполнением единственной инструкции «выбрать следующий элемент списка как Проверяемое_значение». Общий синтаксис инструкции while имеет такой вид:

while (условие) do {тело цикла}.

Эта инструкция представляет собой типичный образец циклической структуры, т.е. при ее выполнении циклически совершаются следующие действия:

проверить условие

выполнить тело цикла

проверить условие

выполнить тело цикл

. .

проверить условие

Эти действия будут продолжаться до тех пор, пока заданное условие будет выполняться.

Как правило, использование циклических структур придает алгоритму большую гибкость по сравнению с явным многократным написанием тела цикла. Рассмотрим такой пример:

Выполнить инструкцию "Добавить каплю серной кислоты" три раза.

Эта циклическая структура эквивалентна такой последовательности инструкций:

Добавить каплю серной кислоты.

Добавить каплю серной кислоты.

Добавить каплю серной кислоты.

Однако невозможно написать аналогичную последовательность, эквивалентную следующему циклу:

while (уровень рН больше, чем 4) do {добавить каплю серной кислоты}

Суть в том, что мы не знаем заранее, сколько капель серной кислоты понадобится в каждом конкретном случае.

А теперь давайте подробно рассмотрим, как осуществляется управление циклом. Может показаться, что эта часть структуры цикла менее важна. Ведь именно в теле цикла непосредственно выполняются требуемые действия (например, добавляются капли кислоты). Поэтому управляющие действия можно рассматривать просто как надстройку, появившуюся только из-за того, что мы решили повторять выполнение тела цикла. Однако опыт показывает, что именно управление циклом чаще всего служит источником ошибок в циклических структурах и, следовательно, требует особого внимания.

Управление циклом состоит из трех операций: инициализации, проверки и модификации (рис. 2), причем все они обязательны для успешного управления циклом. Назначение операции проверки состоит в обеспечении своевременного окончания циклического процесса за счет отслеживания возникновения условия, указывающего, что цикл пора заканчивать. Это условие называют условием завершения цикла. Именно для выполнения операции проверки некоторое условие обязательно указывается при записи каждой инструкции while нашего псевдокода. Однако условие, задаваемое в инструкции while, — это условие продолжения цикла, а условие завершения — это отрицание условия, заданного в инструкции while. Поэтому в инструкции while показанной на рис. 2, условие завершения выглядит следующим образом:

(Искомое_Значение ≤ Проверяемое_Значение) или (больше нет не рассмотренных элементов)

Рисунок 2 - Операции управления циклом

Остальные две операции управления циклом гарантируют, что условие завершения обязательно возникнет. Операция инициализации устанавливает начальное состояние, а операция модификации изменяет его в направлении достижения условия завершения. Например, на рис. 1 операция инициализации выполняется инструкцией, предшествующей инструкции while. В этой операции первый элемент списка устанавливается в качестве текущего проверяемого. Операция модификации в этом случае реализуется в теле цикла, когда интересующая нас позиция (проверяемый элемент) перемещается к концу списка. Таким образом, выполнение операции инициализации и многократное выполнение операции модификации приводят к тому, что условие завершения обязательно будет достигнуто. (Или обнаружится проверяемый элемент, больший либо равный искомому, или будет достигнут конец списка.)

Следует подчеркнуть, что операции инициализации и модификации обязательно должны приводить к заданному условию завершения. Это является важнейшим требованием организации надлежащего управления циклом, поэтому при разработке циклической структуры следует, как минимум, дважды убедиться в том, что оно выполняется. Если пренебречь подобной проверкой, то это может привести к ошибкам даже в простейших случаях. Типичным примером могут служить следующие инструкции:

Число 1while (Число ≠ 6) do {Число Число + 2}

В данном случае условием завершения является выражение Число ≠ 6. Однако переменная Число инициализируется значением 1, а затем увеличивается на 2 на каждом этапе модификации. Таким образом, при выполнении цикла переменной число будут присваиваться значения 1, 3, 5, 7, 9,.... и ее значение никогда не будет равно 6. В результате выполнение данного цикла никогда не закончится.

Существуют два варианта широко распространенных циклических структур, которые отличаются только порядком выполнения операций управления циклом. Первая представлена инструкцией нашего псевдокода:

while (условие) do {действие}

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

Рисунок 3 - Структура цикла while-do

В противоположность этому, в структуре, представленной на рис. 4, указывается, что тело цикла должно выполняться до проверки условия завершения. В результате тело цикла всегда выполняется хотя бы один раз, в то время как в структуре типа while тело цикла может не выполниться ни разу (если условие завершения будет выполнено при первой же его проверке).

Рисунок 4 - Структура repeat-until

В нашем псевдокоде общий синтаксис цикла этого типа имеет следующий вид:

repeat {действие} until (условие)

Рассмотрим конкретный пример:

repeat {взять монету из кармана} until (в кармане нет монет)

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

while (в кармане есть монета) do {взять монету из кармана}

Придерживаясь терминологии нашего псевдокода, будем называть эти структуры оператором цикла с условием продолжения и оператором цикла с условием завершения. Иногда оператор цикла while называют априорным циклом (pretest loop), или циклом с предусловием, поскольку условие завершения проверяется до выполнения тела цикла, а оператор цикла repeat называется апостериорным циклом (posttest loop), или циклом с постусловием, поскольку условие завершения проверяется после выполнения цикла.