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

advertisement
Оператор цикла с предусловием
Синтаксическая диаграмма цикла While
Условие выполнения данного цикла в общем случае задается логическим
выражением, которое указывается после ключевого слова while. Телом цикла
является оператор, который указан после ключевого слова do. Циклы с
предусловием обычно используются в тех случаях, когда количество повторений
цикла заранее неизвестно. Этот цикл выполняется до тех пор, пока условие цикла
истинно.
Особенности цикла while:
1) В цикле с предусловием сначала идёт проверка условия, после чего
выполняется тело цикла, если условие было истинно.
2) После служебного слова do в цикле с предусловием выполняется только
один оператор. Если нужно выполнить несколько операторов, то используется
составной оператор.
3) Цикл while может не выполниться ни разу.
4) Условие в цикле whilе проверяется на один раз больше, по сравнению с
числом повторений тела цикла.
5) Для избежания бесконечного выполнения в теле цикла должен быть
оператор, влияющий на условие.
Пример 1. Сколько раз выполнится тело цикла и сколько раз будет
произведена проверка условия цикла?
eps:=0.01; x:=1;
While x > eps Do x:=x/2;
Построим трассировочную таблицу
Номер итерации
x
x>eps
–
1
1>0.01

Истина
1
0.5
0.5>0.01

Истина
1
2
0.25
0.25>0.01

Истина
3
0.125
0.125>0.01

Истина
4
0.0625
0.0625>0.01

Истина
5
0.03125
0.03125>0.01

Истина
6
0.015625
0.015625>0.01

Истина
7
0.0078125 0.0078125>0.01

Ложь
Ответ: тело цикла выполнится 7 раз, а условие цикла будет проверено 8
раз.
Пример 2. Сколько раз выполнится тело цикла?
x:=0;
While x<=10 Do;
x:=x+1;
Правильный ответ: бесконечно много раз, а точнее программа зациклится,
т.к. в теле цикла стоит пустой оператор.
Пример 3. Требуется написать программу для решения следующей задачи.
В первый день Винни-Пух съел 1 кг мёда, во второй – 2 кг, а каждый
последующий день он съедал столько мёда, сколько съел за два предыдущих дня.
На какой день Винни-Пух съест не менее X кг мёда? X – натуральное число, X>2.
Program puh;
Var yesterday, before, today, i :integer;
Begin
Writeln(’Введите X’); readLn(X);
Before:=1;
Yesterday:=2;
Today:=before+yesterday;
i:=3;
While today<X Do
Begin
Before:=yesterday;
Yesterday:=today;
Today:=before+yesterday;
i:=i+1
End;
2
WriteLn(’На ’,i,’-ый день Вини-Пух съест ’,X,’ кг меда’);
End.
Пример 4. Дано целое число. Подсчитать количество цифр данного числа.
Program sum_cif;
Var m,N,k:integer;
Begin
WriteLn(‘Введите целое число’);
ReadLn(N);
If N=0 then k:=1
{При N=0 особый случай}
Else
Begin
m:=N;
k:=0;
While m<>0 Do
Begin
k:=k+1;
m:=m Div 10;
End
End;
WriteLn(’В числе ’,N,’ – ’,k,’ цифр!’)
End.
Обратите внимание, что в данной задаче избавляться от знака числа с
использованием функции abs() нет необходимости.
Оператор цикла с постусловием
Синтаксическая диаграмма цикла repeat
Условие данного цикла в общем случае задается логическим выражением,
которое указывается после ключевого слова until. Тело цикла располагается
между ключевыми словами repeat и until. Цикл с постусловием выполняется до
тех пор, пока ложно условие цикла. То же самое можно сказать иначе: цикл с
постусловием завершит свою работу, как только условие цикла станет истинным.
3
Поэтому в цикле repeat нужно указывать условие окончания цикла, в отличие от
цикла while, в котором указывается условие продолжения цикла.
Особенности цикла repeat:
1) В цикле с постусловием сначала выполняется тело цикла, и только потом
происходит проверка условия. Поэтому цикл с постусловием обязательно
выполняется хотя бы один раз.
2) В цикле repeat может выполняться любое количество операторов, и
операторные скобки в этом случае не требуются (их роль играют служебные
слова repeat и until).
3) Цикл выполняется пока условие цикла ложно.
4) Проверка условия цикла repeat происходит ровно столько раз, каково
число повторений тела цикла.
5) В теле цикла должен быть оператор, влияющий на условие завершения
цикла.
Пример 5. Пример организации корректного ввода в программе.
Repeat
WriteLn('Введите положительное число');
ReadLn(x);
If x<=0 then Writeln(’Неверный ввод’);
Until x>0;
Пример 6. Составить программу, которая запрашивает числовой пароль
до тех пор, пока он не будет правильно введён. Предусмотреть возможность
завершения программы после 10 неудачных попыток. Если пользователю удалось
правильно ввести пароль, вывести сообщение «Доступ разрешен», в противном
случае – сообщение «Доступ запрещен».
Program kod;
Const parolOK=3424;
Var vvod:integer;
Counter:byte;
Begin Counter:=0;
Repeat
WriteLn(‘Введите пароль’);
4
ReadLn(vvod);
counter:=counter+1;
Until (parolOK=vvod) or (counter=10);
If parolOK=vvod then writeLn(’Доступ разрешен’)
else writeLn(’Доступ запрещен’)
End.
Пример 7. Целое положительное число p называется простым, если оно
имеет только два делителя, а именно 1 и p. Единица (1) простым числом не
считается.
Определить,
является
ли
натуральное
число
N
простым.
Использовать цикл с постусловием.
Program simple;
Var i,N:LongInt;
Begin
WriteLn(‘Введите натуральное число’);
ReadLn(n);
i:=1;
Repeat
i:=i+1
Until (i>n Div 2) Or (n Mod i=0);
If i>n Div 2 Then Writeln(‘Число ‘,n,’ – простое’)
Else Writeln(‘Число ,n,’ – не простое’)
End.
Данное решение избыточно, т.к. достаточно было искать делители до n ,
a не до
n
.
2
Взаимозаменяемость циклов
Алгоритм, написанный с использованием цикла For, может быть легко
переписан с использованием цикла While или с использованием цикла Repeat.
Обратное не всегда справедливо, т.к. специфика циклов While и Repeat
позволяет решать более широкий круг задач, чем цикл For. Задача, решенная с
использованием цикла While, может быть легко решена с использованием цикла
Repeat и наоборот.
5
При преобразовании цикла с параметром в цикл с предусловием важно
учесть, что параметр цикла нужно будет инициализировать и изменять самим,
цикл While этого делать не будет. Общая схема преобразования цикла For в цикл
While:
i:=<нач.знач.>;
while i<=<кон.знач.> do
For i:=<нач.знач.> to <кон.знач.>
begin

do
<тело цикла>
<тело цикла>
i:=i+1;
end;
i:=<нач.знач.>;
while i>=<кон.знач.> do
For i:=<нач.знач.> downto <кон.знач.>
begin

do
<тело цикла>
<тело цикла>
i:=i-1;
end;
Для того чтобы преобразовать цикл While в цикл Repeat нужно построить
отрицание условия из цикла While и применить полученное таким образом
логическое выражение, как условие цикла Repeat. Так же нужно учесть, что тело
цикла Repeat обязательно выполнится 1 раз, в то время как тело цикла While
может не выполниться ни разу. Общая схема преобразование цикла While в цикл
Repeat:
{Cлучай, когда цикл While выполняется 0 раз невозможен}
While <условие> do
<тело цикла>;
Repeat

<тело цикла>
Until not <условие>;
{Возможен cлучай, когда цикл While выполняется 0 раз}
If <условие> then
While <условие> do
<тело цикла>;
Repeat

<тело цикла>
Until not <условие>;
Пример 8. Найти сумму пяти чисел, вводимых пользователем. Написать
три варианта программы с использованием всех трех видов циклов.
Program program_with_for;
6
Var a,S:integer;
Begin
S:=0;
WriteLn(’Определение суммы чисел’);
For i:=1 To 5 Do Begin
Write(’Введите ’,i,’-ое целое число:’); ReadLn(a);
S:=S+a
End;
WriteLn(’Сумма введенных 5-и чисел равна ’,S)
End.
Program program_with_while;
Var a,i,S:integer;
Begin
S:=0;
i:=1;
WriteLn(’Определение суммы чисел’);
While i<=5 Do Begin
Write(’Введите ’,i,’-ое целое число:’); ReadLn(a);
S:=S+a;
i:=i+1
End;
WriteLn(’Сумма введенных 5-и чисел равна ’,S)
End.
Program program_with_repeat;
Var a,i,S:integer;
Begin
S:=0;
i:=1;
WriteLn(’Определение суммы чисел’);
Repeat
Write(’Введите ’,i,’-ое целое число:’); ReadLn(a);
S:=S+a;
i:=i+1;
Until i>5;
WriteLn(’Сумма введенных 5-и чисел равна ’,S)
End.
Пример 9.
Преобразовать следующий алгоритм, переписав его с
использованием цикла repeat.
7
Var N:integer;
Begin
WriteLn(’Введите целое число’);ReadLn(N);
While (N>0) and (N mod 2<>0) do
If N mod 5=0 then N:=N+1
Else N:=N div 3;
WriteLn(’Ваше число после преобразования равно ’,N)
End.
Построим отрицание условия цикла while. Согласно формулам де
Моргана:
not(A and B) = not A or not B
not(A or B) = not A and not B
not((N>0) and (N mod 2<>0)) = not(N>0) or not(N mod 2<>0) =
= (N<=0) or (N mod 2=0).
Учтем также, что возможны входные данные (N – четное или N<0) при
которых тело цикла While не выполнится ни разу. Преобразованная программа:
Var N:integer;
Begin
WriteLn(’Введите целое число’);ReadLn(N);
If (N>0) and (N mod 2<>0) then
Repeat
If N mod 5=0 then N:=N+1
Else N:=N div 3;
Until (N<=0) or (N mod 2=0);
WriteLn(’Ваше число после преобразования равно ’,N)
End.
8
Download