Книга: Песни о Паскале

Глава 15 Айда в Монте-Карло!

Глава 15

Айда в Монте-Карло!


Монте-Карло – весёлый пригород в княжестве Монако, славный своими игорными заведениями. Там, по словам Поэта, жертвуют необходимым в надежде приобрести излишнее. Но к чему нам игорный бизнес, – спросите, – когда мы заняты программой-экзаменатором? Не забывайте, однако, что наш первоклашка пока ещё сам придумывает себе примеры, а это неразумно. Избавим его от ввода сомножителей, – пусть программа сама «изобретает» их. Потому и обращаемся к азартным играм.

Куда ни глянь – то процедура, то функция!

Современные программы очень сложны. И, как любое крупное изделие, заключают в себе труд десятков и сотен специалистов. Трудно поверить, но большинство программистов, работающих над крупным проектом, не видят его в целом, что не мешает им выполнять свою часть работы. Как такое возможно?

Чтобы понять это, оглянитесь вокруг. Обойдутся ли жители города или страны друг без друга? Кем бы ты ни был – врачом, водителем или сапожником – не проживешь без услуг иных граждан, – все мы зависим друг от друга! Но спросите, к примеру, сталевара, куда пойдет выплавляемая им сталь? Он только плечами пожмет!

Работа программистов организована по тем же законам – законам специализации и кооперации. Специализация – это углубление в некоторую узкую область, специальность. Скажем, одни программисты наловчились писать драйверы, другие – базы данных, а третьи – графический интерфейс. Кооперация – это слаженное соединение усилий разных специалистов, – за это отвечает руководящая «верхушка» программного проекта (подобно тому, как правительство руководит страной).

Конечно, «руками водить», распределяя работу, может каждый (некоторые так и думают). Но толку будет чуть, если согласованную работу программистов не поддержать техническими средствами. Современные языки программирования, в том числе Паскаль, такие средства дают. Одно из них – механизм процедур и функций. Процедуры и функции – это готовые «кусочки» программ, выполняющие некоторые оговоренные действия. Иногда их называют общим именем – подпрограммы. Такие «кусочки» могут создаваться разными программистами и сохраняться в специальных файлах – библиотеках. Есть библиотеки и в Паскале.

Для применения библиотечной процедуры или функции достаточно знать её имя и список передаваемых ей параметров. А вот думать о том, как устроена эта процедура внутри, не обязательно. Хочешь выполнить какое-то действие из библиотеки? Тогда помести в нужном месте программы вызов подходящей процедуры и укажи параметры. Кстати, мы с вами уже делаем это, вызывая процедуры Readln и Writeln. В библиотеках Паскаля припасены процедуры и функции на многие случаи жизни, со временем вы узнаете о них больше.

Чем же отличаются функции от процедур? Функции обладают теми же возможностями, что и процедуры, но вдобавок возвращают значение некоторого типа (числовое, логическое или иное). Поэтому вызов функции можно вставлять внутрь выражения, что очень удобно. Как это работает, вы увидите сей же час.

Госпожа удача

Вернемся к нашему экзаменатору, где надо придумать способ формирования случайных чисел в пределах от 1 до 10. Будь под рукой игральный кубик из Монте-Карло, я бы не связывался с компьютером! Впрочем, в библиотеке Паскаля есть такой «кубик» – это функция по имени Random, что переводится как «случайный, беспорядочный». Этой функции необходимо задать один параметр – число N, определяющее предел для случайного числа. В ответ функция возвращает некоторое случайное число в диапазоне от нуля до N-1. Например, в следующем операторе в переменную X попадет некоторое число в диапазоне от 0 до 9.

      X:= Random(10);

Говорят, что функция Random генерирует случайные числа. Чтобы лучше понять, как это работает, введите и запустите следующую программу.

{ P_15_1 – пятикратный вызов функции Random(100) }
begin
      Writeln( Random(100) );
      Writeln( Random(100) );
      Writeln( Random(100) );
      Writeln( Random(100) );
      Writeln( Random(100) );
      Readln;
end.

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

Запустите эту программу ещё пару раз и сравните результаты. Вы заметили, что они повторяются? Так и должно быть! Все потому, что функция Random создает псевдослучайную последовательность чисел. «Псевдо» – значит «не совсем случайную». Эта особенность функции полезна при отладке программ. Но в экзаменующей программе надо получать разные последовательности чисел, иначе смышленые школяры приноровятся к экзаменатору!

Этого можно добиться применением ещё одной процедуры. Она называется Randomize (что значит «уравнять шансы» или «перемешать») и не требует параметров. Вызвав эту процедуру единожды в начале программы, мы смешаем карты и заставим функцию Random при повторных запусках программы генерировать разные последовательности чисел. Итак, вставьте вызов процедуры Randomize в начало программы и повторите опыты, запустив программу несколько раз подряд.

{ P_15_2 – пятикратный вызов функции Random(100) после Randomize }
Begin
      Randomize;
      Writeln( Random(100) );
      Writeln( Random(100) );
      Writeln( Random(100) );
      Writeln( Random(100) );
      Writeln( Random(100) );
      Readln;
end.

Теперь от успешного финиша проекта нас отделяет один шаг: придумаем способ генерировать числа от 1 до 10 (а не от 0 до 9). Очевидно, что простое арифметическое выражение решает эту проблему.

      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) так, чтобы они не совпадали. Сделайте то же самое для трех чисел.

Оглавление книги

Оглавление статьи/книги

Генерация: 0.815. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз