Вопросы для проверки знаний.
End.
Repeat
Begin
End.
Repeat
Begin
End.
Begin
Until False
Repeat
оператор 1;
...
oператор n
Вместо явной подстановки в логические выражения циклов логических значений True (False) для организации бесконечных циклов в их выражения могут быть подставлены логические условия, которые всегда истинны (ложны). Например, условия (1<2), (x*x+y*y≥0) всегда истинны; условия (1≥2), (x*x+y*y<0) – всегда ложны.
Прерывание бесконечных циклов во всех языках программирования прямо или опосредованно зависит от действий пользователя, в результате которых в теле цикла срабатывают Break-подобные операторы (в Паскале – оператор break). Теоретически для выхода из бесконечного цикла можно использовать оператор безусловного перехода GOTO, но в соответствии с принципами структурного программирования лучше применять специальный оператор break.
Пример 1 использования оператора break для прерывания бесконечного цикла в зависимости от реакции пользователя на запрос программы. Рассмотрим код программы, который реализует теоретически бесконечное наращивание счетчика i и вывод его значений на экран до тех пор, пока пользователь не прекратит выполнение цикла путем ввода в программу любого сообщения, отличающегося от ’y’:
var s:char; i:integer;
i:=0; {присвоение начального значения целочисленному счетчику i}
while True do {оглавление бесконечного цикла}
begin{открытие тела бесконечного цикла}
i:=i+1; Write (’counter=’,i); {наращивание значения счетчика i и его вывод}
Write(’ Enter request for cycle continue (y - yes, any others - no)’);
ReadLn(s); {получение ответа от пользователя на запрос о продолжении цикла}
if not(s='y')then break{реакция - прерывание цикла при значениях s,не равныхy}
end; {закрытие тела бесконечного цикла }
Одном из основных случаев применения потенциально бесконечного цикла является получение гарантированного правильного ответа пользователя на запрос программы в том случае, когда задано допустимое множество вариантов ответа. Запрос программы и анализ ответа пользователя повторяются до тех пор, пока пользователь не даст тот ответ, который входит в допустимое множество.
Пример 2. От пользователя необходимо при помощи бесконечного цикла гарантировано получить ответ в виде одного символа, который должен быть только одной из цифр 1,2,3,4,5. При получении правильного ответа v необходимо выйти из цикла и вывести на экран сообщение "variant = v ".
Решение. Так как должен быть выдан хотя бы один запрос, то применяем циклrepeat, который станет практически бесконечным, если пользователь в каждой итерации будет вводить символы, отличные от цифр 1,2,3,4,5. Обозначим получаемый от пользователя символ через v и присвоим ему тип char для того, чтобы пользователь мог вводить любые символы без аварийного выхода из программы из-за несоответствия типов. Так как коды цифр 1,2,3,4,5 в кодировке ASCII стоят подряд, переводим все проверяемые величины в ее порядковые номера при помощи функции ord. Полный код решения задачи:
var v:char; i,i1,i5:integer;
i1:=ord('1');i5:=ord('5'); {перевод символов '1','5' в порядковые номера кодировки ASCII}
Write(' Enter variant number (1,2,3,4 or 5):');{запрос на ввод номера варианта }
ReadLn(v);{получение ответа от пользователя на запрос о номере варианта}
i:=ord(v); {перевод символа v в порядковый номер кодировки ASCII}
until (i1<=i)and(i<=i5);{анализ ответа и уход на повтор запроса при неправильном ответе}
WriteLn(' variant =', v); {вывод номера варианта после выхода из цикла}
В рассмотренном примере при вводе строковых сообщений, состоящих из двух и более символов, программа будет анализировать только первый символ, поскольку величине v присвоен тип char (одиночный символ).
Пример 3. От пользователя необходимо при помощи бесконечного цикла гарантировано получить ответ в виде одного символа, который должен быть только одна из заглавных латинских букв A,B,C,G,H,I.. При получении правильного ответа v необходимо выйти из цикла и вывести на экран сообщение "variant = v ".
Решение. Для формирования условия проверки в алгоритме решения данной задачи можно использовать тот факт, что в кодировке ASCII коды заглавных букв A,B,C,D,E,F, G,H,I стоят подряд. При этом коды букв в парах, равноотстоящих от краев (A,I), (B,H), (C,G), (D,F), будут отличаться от кода средней буквы последовательности E, соответственно, на 4,3,2. Это свойство можно использовать для задания условия проверки принадлежности введенной буквы l заданному множеству с использованием кодов k(l), k(E) букв l и E:2≤ïk(l)-k(E)ï≤4. Это условие вставляем в цикл repeat.Для краткостизначение модуля разности ïk(l)-k(E)ïприсвоим переменнойabs_d:
var v:char; kv,kE,abs_d:integer;
kE:=ord('E'); {перевод символа E в порядковый номер кодировки ASCII}
Write(’ Enter variant number (A,B,C,F,G or H):’); {запрос на ввод буквы }
ReadLn(v);{получение ответа от пользователя }
kv:=ord(v); {перевод символа v в порядковый номер кодировки ASCII}
abs_d:=abs(kv-kE);
until (2<=abs_d)and(abs_d<=4);{анализ ответа, повтор запроса при неправильном ответе}
WriteLn(' variant =', v); {вывод номера варианта после выхода из цикла}
Так как в примерах 2 и 3 требуется получать от пользователя гарантированный ответ, то для ввода его ответов использован операторreadln.
1. Что в теории программирования называют бесконечным циклом и какое состояние выполнения программы называют зацикливанием ?
2. Как практически проявляется зацикливание ?
3. При решении каких задач используются бесконечные циклы ?
4. Как в Паскале можно задать бесконечный цикл ?
5. Как в Паскале практически реализуется выход из бесконечного цикла ?
6. Как бесконечный цикл используется для получения гарантировано правильного ответа от пользователя ?
Практическое задание.
1. На основе использования программного кода из примера 1 п.6.6. разработать код программы, в которой компьютер играет в кости с пользователем. Для простоты использовать одну игральную кость, на шести гранях которой нанесены от 1 до 6 точек. После каждого выбрасывания кости на экран выдается результат, а также запрос на дальнейшее продолжение игры. Для получения случайных целочисленных значений в интервале от 1 до 6 использовать стандартную функцию random с предварительным обращением к процедуре Randomize.