Тема 4. Циклические алгоритмы (операторы цикла)

Тема 3. Ветвящиеся алгоритмы (оператор выбора)

В некоторых задачах формулируются условия, содержащие три и более исходов (альтернатив, вариантов действий). Использование условного оператора в подобных задачах, может приводить к созданию громоздких структур (ветвлений), поэтому желательно в таких случаях применять оператор выбора. Запись оператора выбора на ЯП Паскале выглядит следующим образом:

case <селектор> of

<список вариантов 1>: <оператор1>;

<список вариантов 2>: <оператор2>;

<список вариантов N>: <операторN>

else <альтернативный оператор>

end;

Оператор case состоит состоит из селектора (переменной целого, символьного или логического типа) и списка операторов, каждому из которых предшествует список вариантов, представляющий собой значение того же типа, что и селектор. Значения, входящие в список вариантов, разделяются запятыми, а диапазоны значений задаются с использованием "..". При работе оператора case будет выполнен тот входящий в него оператор, в чьём списке вариантов окажется текущее значение селектора. Если ни один из списков вариантов не содержит значения селектора, то выполняется оператор, стоящий за словом else (альтернативный оператор), если ветвь else отсутствует, то ничего не выполняется. После ":" допустимо выполнение только одного оператора, поэтому для выполнения нескольких операторов необходимо использовать составной оператор. Оператор выбора закрывается end. Входить внутрь оператора выбора по какому-либо оператору перехода goto, находящемуся вне оператора варианта, нельзя. Выполнение оператора варианта сводится к выполнению только одного из входящих в его состав операторов, поэтому переходить с одного из них на другой с помощью оператора перехода goto запрещается.

Пример 3.1п. Оператор выбора. Часть I.

В зависимости от остатка от деления N (целое число) на 8 выполнить следующее: если остаток равен 0, то значению N надо присвоить ноль; если остаток равен 1 или от 3 до 5, то N заменить противоположным значением; если остаток равен 2 или 6, то N - удвоить; если остаток равен 7, то значение оставить без изменений.

Сначала определимся, какие переменные понадобятся при написании программы. Понадобиться только одна переменная N, которая будет целого типа, а ее значение будет задаваться с клавиатуры. В качестве селектора в операторе выбора будет выражение, вычисляющее остаток от деления на 8. Для вычисления остатка от деления будет использоваться функция mod. В итоге получаем следующую программу.

Var N:integer; {раздел описания переменных, в котором регистрируется переменная N - типа integer}

begin {начало раздела операторов}

readln(N); {задание значения N через оператор ввода}

case N mod 8 of {начало оператора выбора, вычисление значение селектора}

0: N:=0; {присваивается N нулю в случае остатка равного 0}

1,3..5: N:=-N; {присваивается N противоположное значение, если остаток равен 1,3…5}

2,6: N:=2*N; {N удваивается, если остаток равен 2 или 6}

end; {закрытие оператора выбора}

writeln('New N=',N); {вывод на экран нового значения N}

readln; {ожидание нажатия клавиши Enter}

end. {конец программы}

Тема 4. Циклические алгоритмы (операторы цикла)

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

оператор цикла с предусловием;

оператор цикла с постусловием;

арифметический оператор цикла (оператор цикла с параметром).

Рассмотрим их по порядку.

Оператор цикла с предусловием

Общий вид оператора цикла с предусловием на ЯП Паскаль следующий:

while <логическое выражение> do <оператор>;

Выполнение оператора начинается с вычисления значения логического выражения. Если оно имеет значение true (истина), то выполняется оператор, стоящий после do. Выполнение цикла продолжается до тех пор, пока логическое выражение не примет значение false (ложь). Если выражение равно false на первом же витке цикла, то работа цикла завершится, а входящие в него операторы не выполнятся ни разу. Поскольку в цикле типа while-do условие его работы проверяется до выполнения входящего в него оператора, такой цикл называется "оператор цикла с предусловием". Схематично работу оператора цикла с предусловием можно представить следующим образом.

Тема 4. Циклические алгоритмы (операторы цикла) - student2.ru

Оператор цикла с постусловием

Запись оператора цикла с постусловием имеет вид:

repeat <список операторов> until <логическое выражение>;

Оператор цикла с постусловием начинается с выполнения списка операторов внутри цикла (начиная с оператора, идущего после repeat, и заканчивая оператором, стоящим перед until). Затем проверяется истинность логического выражения, стоящего после слова until. Если это условие принимает значение true (истина), то осуществляется выход из цикла. Если же значение логического выражения false (ложь), то выполнение операторов "тела" цикла повторяется, после чего снова проверяется истинность логического условия. Схематично работу оператора цикла с постусловием можно представить следующим образом.

Тема 4. Циклические алгоритмы (операторы цикла) - student2.ru

Арифметический оператор цикла

Запись арифметического оператора цикла на ЯП Паскаль имеет вид:

for <счетчик>:=<н.з.> to <к.з.> do <оператор>;

Где <счетчик> - параметр цикла (счетчик повторов), является переменной порядкового типа (целого, символьного), меняется в пределах от <н.з.> до <к.з.> (<н.з.> - начальное значение, <к.з.> - конечное значение) с шагом единица. Оператор - любой простой или составной оператор, который необходимо повторить несколько раз. Выполнение оператора происходит для каждого значение параметра цикла. Тип начального и конечного значений должен соответствовать типу счетчика.

Существует другой вид оператора цикла с параметром:

for <счетчик>:=<н.з.> downto <к.з.> do <оператор>;

Отличием от предыдущей записи является то, что шаг, с которым изменяется параметр цикла, равен минус единица. Значение счетчика убывает на каждом витке цикла.

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

нельзя задавать шаг изменения значения параметра, отличный от 1 или -1;

не рекомендуется изменять внутри цикла значения параметра цикла, его начальное и конечное значения(может произойти зацикливание);

Особенности использования циклов

Арифметический цикл (for-to-do) обычно используется в тех случаях, когда заранее известно, сколько раз должно быть выполнено "тело" цикла, иначе рекомендуется использовать оператор цикла с постусловием (repeat-until) или предусловием (while-do).

Цикл с постусловием (repeat-until) используется, если необходимо, чтобы тело цикла выполнялось, по крайней мере, один раз.

Цикл с предусловием (while-do) используется, когда требуется, чтобы проверка производилась прежде, чем выполнится тело цикла.

Согласно формальным правилам ЯП Паскаль, в цикле с параметром (for-to-do) и с предусловием (while-do) после do выполняется только один оператор. Если требуется, чтобы выполнялось множество операторов, то тогда необходимо использовать составной оператор (begin-end), объединяя, тем самым, это множество в один оператор. В цикле с постусловием (repeat-until) операторные скобки не требуются.

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

while i<=10 do write('None stop!');

при значении "i", пришедшим первоначально в цикл меньшим или равным десяти, выводит на экран друг за другом строку "None stop!" до тех пор, пока программа принудительно не будет завершена. Остановить бесконечное выполнение "тела" цикла можно, нажав сочетание клавиш Ctrl+Break, после чего надо нажать клавиши Enter, F9 и Esc. Во избежание такой ситуации, необходимо, чтобы операторы, входящие в "тело" цикла, влияли на условие, определяющее завершение цикла:

i:=1;

while i<=10 do

begin write('Cicle is right!');

i:=i+1;

end;

В этом фрагменте программы цикл выполнится ровно 10 раз, после чего компьютер перейдет к следующим командам (операторам).

При использовании операторов цикла с предусловием (while-do) и постусловием (repeat-until) необходимо быть осторожным в тех случаях, когда в логическом выражении (условии работы или окончания цикла) фигурируют переменные вещественного типа. Следует помнить, что в компьютере значения выражений вещественного типа вычисляются приближенно, т.е. с некоторой погрешностью. Например, результатом какого-то выражения после ряда вычислений должно быть вещественное число равное 1.0, компьютер в результате округлений после всех вычислений может получить число равное, например, 0.999999999 или 1.000000001 . Поэтому фрагмент:

var i, n : real;

repeat

until i=n;

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

until i<=n;

или

until i>=n;

или

until abs(i-n)<=1e-6;

Наши рекомендации