Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
delphi / песни о паскале.pdf
Скачиваний:
63
Добавлен:
26.03.2016
Размер:
5.16 Mб
Скачать

Глава 13 Правда и кривда

Что приятней, получать подарки или дарить их? Сейчас узнаем: вот вам автомобиль — дарю! Будете в школу на нём гонять. Впрочем, мой подарок не бескорыстен, и взамен я жду вашей помощи.

«Автомобиль — не роскошь, а средство передвижения» — утверждал персонаж книги Ильфа и Петрова. Что бы сказал он сегодня, томясь в унылых пробках? Теперь и вы за рулём, значит, дорожные пробки — наша общая напасть. Так будем бороть её вместе! Ведь всё для этого есть, — в каком веке то живем! Что ни автомобиль — то бортовой компьютер, а космос ломится от спутников! Создадим программу для бортового компьютера автомобиля. Компьютер будет принимать сигналы от спутников системы ГЛОНА́СС (это ГЛОба́льная НАвигацио́нная Спу́тниковая Систе́ма) и сообщать о дорожных пробках. К деталям этого проекта обратимся позже, а начнем, как водится, издалека — из космоса.

Есть ли жизнь на Марсе?

Об этом всё ещё спорят ученые, не находя ответа. «Спросите что попроще, — скажете, — например, мой возраст». Но если бы здесь отвечал компьютер, то вопрос о Марсе он счел бы простым, а вопрос о возрасте — сложным. Почему?

А потому, что о марсианской жизни можно ответить односложно: «да» или «нет». А сообщая возраст, надо указать какое-то число или дату рождения. Ещё сложнее растолковать компьютеру, как выглядит, к примеру, цветок или бабочка, тут не отделаться одним числом, а тем паче ответом «да» или «нет». Такие вопросы требуют сложного ответа, несущего много информации. Стоп! Я упомянул информацию? Вот о ней — об информации — потолкуем подробней.

Информация и её мерило

Компьютер обрабатывает информацию, — это все знают. Только почему, соорудив столько программ, мы всё ещё не знаем, что такое информация? Её трактуют по-разному, одно из определений таково: «информация это то, что устраняет неопределенность». В самом деле, задавшись неким вопросом, мы испытываем неопределенность, а получив ответ, избавляемся от неё, и на душе становится легче.

Получить ответ — это значит получить информацию. А сколько мы при этом её получаем, чем измерить это количество? Математики догадались, что меньше всего информации заключено в односложном ответе: «да» или «нет». Это количество взято за мерило и названо битом (по-английски «BIT»). Крупные единицы информации содержат много битов: байт — восемь битов, 1 Кбайт (читается «кибибайт») — 1024 байта и так далее, — об этом можно прочитать в школьных учебниках. Стало быть, ответ на вопрос «быть или не быть?» содержит всего один бит информации, — компьютер считает такие вопросы простыми.

86

Глава 13

Правда и кривда

Ответы на сложные вопросы (например, как выглядит то, или это) могут содержать миллионы байтов. В этом легко убедиться по размеру файла с какой-нибудь фотографией или фильмом.

Но вернемся к биту. Природная склонность компьютера к «простым» вопросам и односложным ответам объясняется устройством его электронной памяти, состоящей из битовых ячеек — триггеров. Не вдаваясь в технические детали, скажу лишь, что такая ячейка может находиться в одном из двух устойчивых состояний, которые часто обозначают цифрами «0» и «1». С тем же успехом их можно обозначить иначе, например: «да» и «нет». Или так: «истина» и «ложь», «правда» и «кривда», «крестик» и «нолик». Короче говоря, название — дело вкуса, важно лишь то, что триггер хранит один бит информации. Эта особенность компьютеров отразилась во многих языках программирования, в том числе в Паскале.

Булевы переменные

Итак, элемент памяти компьютера — триггер — хранит наименьшую порцию информации — один бит. А в Паскале есть надлежащий тип данных для хранения и обработки битов, он называется булевым (ударение на первом слоге) — по имени английского математика Буля. Другое название этого типа данных — логический. Булевы переменные объявляют так:

var A, B, C : Boolean;

Здесь объявлены три переменных булевого типа.

Булевы переменные, подобно триггеру, могут содержать лишь одно из двух значений: TRUE — «истина» или FALSE — «ложь». Это зарезервированные слова Паскаля, и попытка присвоить логическим переменным другие значения будет пресечена компилятором. Вот примеры правильного обращения с булевыми переменными:

A:= true;

B:= false;

C:= B;

А вот грубые ошибки:

A:= ’true’;

B:= ’false’;

C:= ’B’;

Повторяю: TRUE и FALSE — это зарезервированные слова, а не строковые константы, они пишутся без апострофов.

87

Глава 13

Правда и кривда

Ввод и вывод булевых данных

Ввод и вывод — это первое и последнее звено в цепочке обработки данных. Прежде, чем обрабатывать данные, надо освоить их ввод и вывод. Рассмотрим, как это делается с булевыми данными.

С выводом проблем нет, поскольку процедура Writeln напечатает их словами «TRUE» и «FALSE». Вот небольшая программа, испытайте её.

var B : Boolean;

 

begin

 

B:= false;

Writeln(B);

B:= true;

Writeln(B);

end.

Вводить булевы данные чуть сложнее, поскольку процедура Readln, к сожалению, не умеет этого делать. Как быть? «Нормальные герои всегда идут в обход», — поется в песне. Осуществим хитрый манёвр: для ввода булевых значений воспользуемся переменной другого типа, например, строковой, а затем преобразуем введенную строку в булев тип.

Условимся, что значению TRUE будет соответствовать ввод в строковую переменную символа «1», а FALSE — любой другой строки. Тогда булево значение в переменную B можно ввести следующим манером.

var S : String; B : Boolean;

begin

Writeln(’Введите “1” для TRUE и прочее – для FALSE’);

Readln(S);

if S=’1’ then B:= true else B:= false; Writeln(B); Readln;

end.

Просто? Но можно сделать ещё проще, прибегнув к логическому выражению.

Логические выражения

Данные логического типа можно получать в результате не совсем обычных вычислений. В этих вычислениях порой не увидишь ни чисел, ни арифметических действий, — речь идет о логических выражениях. Например, сравнивая две строки, вы задаетесь вопросом, равны ли они? Ответом может быть либо «да», либо «нет», или, выражаясь на языке Паскаль, TRUE или FALSE. Следовательно, сравнение строк, которое мы применяли в условных и циклических операторах, — это логическое выражение. А раз так, то результат сравнения можно присвоить

88

Глава 13

Правда и кривда

булевой переменной. В приведенном выше примере вместо условного оператора можно записать выражение:

B := S=’1’;

{ равносильно if S=’1’ then B:= true else B:= false }

Здесь справа от знака присваивания стоит логическое выражение S=’1’, и в переменную B попадет TRUE, если S будет содержать строку «1» и FALSE — в любом другом случае.

Булевы переменные и выражения применяют везде, где требуется проверка условия, например, в условном и циклическом операторах:

if B

then . . . { выполняется, если B=true } else . . . { выполняется, если B=false }

repeat

{ цикл выполняется, пока B=false } until B

Замечу здесь, что «if B then...» равносильно «if B=TRUE then...».

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

С высоты птичьего полета

Напомню, что мы работаем над программой для навигатора автомобиля, принимающего сигналы от спутников системы ГЛОНАСС. Из космоса прекрасно видны все улицы и пробки города. Пусть все возможные маршруты от дома до школы известны заранее, а спутник сообщает лишь о том, открыта ли для движения та или иная улица. Если улица открыта, спутник сообщает об этом значением TRUE, а иначе — значением FALSE. Увы, к настоящему спутнику мы пока не подключены, и вводить данные о пробках придется вручную. Результатом работы нашей программы будет сообщение о том, можно ли проехать в школу

(TRUE), или нет (FALSE).

Вот первый маршрут. Предположим, путь от дома до школы пролегает по двум улицам так, как показано на рис. 31.

 

Дом

 

 

Улица A

 

Улица B

 

 

Школа

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 31 – – Схема первого маршрута

89

Глава 13

Правда и кривда

Очевидно, что отразить состояние двух улиц можно двумя булевыми переменными, назовем их A и B. Объявим переменные и введем данные в них.

var A, B : Boolean; S: string;

begin

Write(’Улица A открыта? ’); Readln(S); A:= S=’1’;

Write(’Улица B открыта? ’); Readln(S); B:= S=’1’;

Здесь, как мы условились раньше, значение TRUE вводится цифрой «1».

Обратите внимание на новую для вас процедуру Write, — это «младшая сестра» процедуры Writeln. В отличие от «старшей сестры», после вывода сообщения она не переводит курсор на следующую строчку, — это удобно при запросе данных.

Ну-с, данные со спутника введены, и можно заняться их обработкой. Ясно, что для проезда в школу обе улицы должны быть открыты. Условными операторами это нехитрое рассуждение можно выразить так.

S:=’Топай пешком’; if A then

if B then S:=’Поезжай на машине!’;

Исходное значение — «Топай пешком» — заносим в переменную S заранее. Оно изменится тогда, когда обе булевы переменные станут равны TRUE. Согласитесь, это решение из двух условных операторов оказалось несложным. Но до поры до времени. Что, если маршрутов станет много, и каждый будет пролегать через несколько улиц? Программа превратится в нагромождение условных операторов, больше похожее на хаос землетрясения! Страшно? Тогда рассмотрим другой подход. Суть его в том, чтобы выразить решение на обычном человеческом языке, а затем превратить это высказывание в логическое выражение.

Решение нашей задачи можно высказать так: «проехать можно, если открыта улица A И открыта улица B». Обратите внимание на подчеркнутый мною союз «И». Чтобы превратить это рассуждение в логическое выражение и записать на Паскале, надо лишь перевести союз «И» на английский язык — это будет «AND», а названия улиц заменить логическими переменными A и B. И вот результат такого перевода.

if A and B

then S:=’Поезжай на машине!’

else S:=’Топай пешком!’;

Вместо двух условных операторов остался один. Готовая программа будет такой.

90

Глава 13

Правда и кривда

{ P_13_1 – первый маршрут проезда } var A, B : Boolean; S: string; begin

{ ввод данных со «спутника» } Write(’Улица A:’); Readln(S); A:= S=’1’; Write(’Улица B:’); Readln(S); B:= S=’1’; { решение }

if A and B

then S:=’Поезжай на машине!’ else S:=’Топай пешком!’;

Writeln(S); Readln

end.

Испытайте программу при разных сочетаниях входных данных и проверьте, не врёт ли она?

Теперь рассмотрим другой маршрут, здесь попасть в школу можно по любой из двух улиц (рис. 32).

Улица A

Дом

 

 

 

 

Школа

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Улица B

Рис. 32 – Схема проезда, второй вариант

Обычным языком молвим так: «проезд возможен, если открыта улица A ИЛИ открыта улица B». Союз «ИЛИ» тоже припасен в Паскале, по-английски он пишется «OR». В этом случае решение будет таким.

if A or B

then S:=’Поезжай на машине!’

else S:=’Топай пешком!’;

А вот маршрут на рис. 33 более замысловат.

91

Глава 13

Правда и кривда

 

Дом

 

 

Улица A

 

Улица B

 

 

Школа

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Улица C

 

Улица D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Улица E

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 33 – Схема проезда, третий вариант

Слабо ли вам выразить решение для этого случая? Сказать на обычном языке легко: «проехать можно, если открыта A И открыта B ИЛИ открыта C И открыта D ИЛИ открыта E». Слово «улица» я пропустил. Всё, решение готово! Осталось лишь перевести его на язык Паскаль.

if A and B or C and D or E

then S:=’Поезжай на машине!’

else S:=’Топай пешком!’;

Как просто! Здесь опять подчеркнуто логическое выражение. Только теперь оно составлено из булевых переменных и булевых операций AND (И) и OR (ИЛИ). Иногда эти операции называют логическим умножением и логическим сложением. Сходство с арифметикой здесь в том, что каждая логическая операция обладает в выражении своим старшинством: умножение AND выполняется раньше сложения OR. Когда эту последовательность надо изменить, применяют скобки. Пример такого рода показан на рис. 34 (перекресток).

 

 

 

 

 

Улица A

 

 

 

Улица C

 

 

 

Дом

 

 

 

 

 

 

 

 

 

 

 

Школа

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Улица B

 

 

 

Улица D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 34 – Схема проезда, четвертый вариант

Сначала скажем словами: «проехать можно, если открыта A ИЛИ открыта B И открыта C ИЛИ открыта D». Переведя на Паскаль буквально, без скобок, получим:

if A or B and C or D

then S:=’Поезжай на машине!’

else S:=’Топай пешком!’;

Поскольку логическое умножение выполняется раньше сложения, Паскаль поймет это так: A or (B and C) or D. Но это не то, что мы хотели! Правильно будет записать наше решение со скобками:

92

Соседние файлы в папке delphi