Вопросы для проверки знаний.

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.