X:= 1+ Random(10); { генерация чисел от 1 до 10 }
Сейчас вы готовы написать второй вариант экзаменатора, вот каким он может быть (новые операторы, как обычно, выделены курсивом).
{ P_15_3 – программа-экзаменатор, версия 2 }
var A, B, C : integer; { сомножители и произведение }
begin
Randomize; { смешиваем «карты» }
repeat
A:= 1+ Random(10); B:= 1+ Random(10);
Write(’Сколько будет ’, A,’ x ’,B, ’ ? ’);
Readln(C);
if C=0 then break; { завершение цикла, если C=0 }
{ проверяем правильность вычисления }
if A*B=C
then Writeln(’Молодец, правильно!’)
else Writeln(’Ошибка, повтори таблицу умножения!’);
until false; { бесконечный цикл! }
end.
Обратите внимание на вывод задания для умножения.
Write(’Сколько будет ’, A,’ x ’,B, ’ ? ’);
Здесь процедура Write содержит уже пять параметров: две числовые переменные и три строковые константы. Так, при A=3 и B=7 на экране появится вопрос: «Сколько будет 3 x 7 ?». Остальные операторы программы обойдутся без моих пояснений.
Итоги• В языках программирования предусмотрены средства для согласованной работы программистов, одно из них – библиотеки процедур и функций.
• Отличие процедур от функций состоит в том, что процедура лишь выполняет оговоренные действия, а функция вдобавок возвращает данные некоторого типа.
• Для генерации случайных последовательностей чисел применяют функцию Random и процедуру Randomize.
• Функция Random(N) возвращает псевдослучайное число, лежащее в пределах от 0 до N-1. При повторных запусках программы эта серия чисел повторяется, если заранее не вызвана процедура Randomize.
• Вызов процедуры Randomize в начале программы приводит к генерации функцией Random разных серий псевдослучайных чисел.
А слабо?А) В каких пределах будут генерироваться числа следующими выражениями:
10+Random(10);
Random(20);
Random(10) + Random(10);
Random(5) + Random(5) + Random(5) + Random(5);
Проверьте себя на компьютере!
Б) Сколько чисел будет напечатано следующей программой? Испытайте на практике.
var x : integer;
begin
repeat
x := Random(20);
Writeln(x);
until x=1;
end.
В) А если в начало предыдущей программы вставить Randomize? Можно ли предсказать результат? Или слабо?
Г) Найдите способ сформировать ряд случайных булевых значений (False, True), напечатайте 20 из них. Подсказка: булевы значения получаются сравнением двух случайных целых чисел.
Д) Сгенерируйте два случайных числа (в диапазоне от 1 до 10) так, чтобы они не совпадали. Сделайте то же самое для трех чисел.
Глава 16Делу время, а потехе час
Наши программы – и часовой, и экзаменатор – такие любопытные! Все спрашивают что-то: то пароль им подавай, то таблицу умножения! Не поменяться ли с компьютером местами? Теперь мы будем спрашивать, а он – отвечать.
Вот веселая и глупая игра: «вопрос-ответ», суть которой такова. Две колоды карточек – одну с вопросами, а другую с ответами – тасуют и кладут рубашками вверх. Кто-то из сидящей вокруг стола компании берет наугад карточку из «вопросительной» колоды и читает вопрос своему соседу. Тот вынимает наугад карточку из колоды с ответами и оглашает его. К примеру, на вопрос «Как пройти в библиотеку?» можно получить ответ: «Волк, коза и капуста».
Создадим нечто похожее для игры на компьютере, он будет отвечать на вопросы, вводимые пользователем с клавиатуры. Разумеется, что ответы заготовим в программе заранее, а выбирать их будем случайно.
Потемкинская лестницаВ первую минуту эта задачка представится вам легкой забавой, – я попробую угадать ход ваших мыслей. Во-первых, не будем обращать внимание на вопрос пользователя, – для подготовки ответа он не важен. После ввода вопроса сгенерируем случайное число и выберем один из заранее подготовленных ответов, согласуясь с этим числом. А как организовать выход из программы? Вот тут вопрос пользователя будет кстати, – приняв пустой вопрос, мы завершим программу. Этим мыслям отвечает блок-схема на рис. 38.
Рис.38 – Блок-схема выбора из четырех вариантовРассмотрим условный оператор, выбирающий один из четырех ответов на основе случайного содержимого переменной R.
if R=1
then S:=’Ответ 1’
else if R=2
then S:=’ Ответ 2’
else if R=3
then S:=’ Ответ 3’
else S:=’ Ответ 4’;
Вложенные друг в друга условные операторы образуют «лесенку», – такое расположение удобно для чтения программы. А если заготовить больше ответов? Тогда «лесенка» дорастет до потемкинской лестницы, что в чудном городе Одессе!
Эта проблема – типичный случай в программировании. На сей случай в Паскале запасен оператор выбора CASE (что так и переводится – «случай»). В отличие от оператора IF, содержащего лишь две ветви, в операторе CASE их много – на все случаи жизни. Оператор записывают следующим образом:
case X of
n1: Оператор_1;
n2: Оператор_2;
...
else Оператор_n
end;
Конструкция построена на четырех ключевых словах CASE-OF-ELSE-END. Выражение целого типа X служит условием, по которому выбирается одна из числовых меток: n1, n2 и так далее (метки – это целые числа). Работает оператор так. Если выражение X = n1, то выполняется оператор_1, если X = n2, то выполняется оператор_2 и так далее. Если X не соответствует ни одной метке, сработает оператор, указанный после ELSE. А если ветвь ELSE отсутствует? Тогда ничего не выполняется.
Вот пример. Если в результате вычисления выражения Random(20)+1 будет получено число от 1 до 3, то переменной S будет присвоено соответствующее слово, а иначе она станет пустой.
case Random(20)+1 of
1: S:= ’Первый’;
2: S:= ’Второй’;
3: S:= ’Третий’;
else S:= ’’;
end;
Если оператор CASE применить к нашей шуточной (или нешуточной) программе, то получится вот что.
{ P_16_1 – игра «вопрос – ответ» }
var S: string;
begin
Randomize; { чтобы случайный ряд не повторялся }
repeat
Write(’Ваш вопрос: ’); Readln(S);
if S=’’ then break; { завершение цикла, если строка пуста }
case Random(5) of
0: S:=’Когда рак на горе свиснет’;
1: S:=’После дождика в четверг’;
2: S:=’За углом налево’;
3: S:=’Это элементарно, Ватсон!’;
else S:=’Не знаю, я не местный’;
end;
Writeln(S); { печать ответа }
until false; { бесконечный цикл }
end.
Добавьте несколько смешных ответов, увеличив соответственно параметр функции Random, а затем испытайте программу на своих приятелях.
Итоги• Для условных переходов со многими ветвями в Паскале предусмотрен оператор выбора CASE-OF-ELSE-END.
• Каждая ветвь оператора CASE начинается с числовой метки, за которой следует выполняемый оператор.
• Метки могут следовать в любом порядке (не только по возрастанию).
• Ветвь оператора CASE выбирается в зависимости от числового выражения в условии. Если ни одна метка не соответствует условию выбора, выполняется оператор, указанный после ELSE. Если ветвь ELSE не указана, то ничего не выполняется.
• Для исполнения внутри ветви нескольких операторов их объединяют в блок BEGIN-END.
А слабо?А) Какой ответ будет выпадать чаще других, если условием в операторе CASE нашей программы поставить выражение Random(100)?
Б) Напишите программу, которая бы запрашивала номер дня недели, и в ответ печатала бы название этого дня («понедельник», «вторник» и так далее).