Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тurbo Pascal 7+.doc
Скачиваний:
12
Добавлен:
24.12.2018
Размер:
10.09 Mб
Скачать

10.6. Порядок описания переменных, процедур и других конструкций Паскаля

В разделе 4.6 было сказано, что перед тем как выполниться программа на Паскале компилируется на машинный язык. При компиляции она просматривается сверху вниз, при этом Паскаль следит, чтобы ни одна переменная, процедура не была в тексте программы применена выше, чем описана. Как это понимать?

Переменные описаны в разделе VAR. Под применением переменной будем понимать ее упоминание в среде операторов в описаниях процедур, то есть там, где эта переменная должна быть активизирована в процессе выполнения программы.

Таким образом оператор VAR всегда размещается в самом верху программы и если это условие не будет выполнено, то Паскаль выдаст сообщение об ошибке.

Все эти рассуждения также применены к процедурам и другим конструкциям. Так описание процедуры Tree (пример выше) нельзя было помещать ниже описания процедуры Landscape? Так как в процедуре Landscape процедура Tree применяется 3 раза.

Иногда возникает необходимость, чтобы не только процедура P1 обращалась к процедуре P2, но и процедура P2 обращалась к процедуре P1. Пример такого обращения показан в такой программе:

PROCEDURE P2; описание процедуры P2

BEGIN …

P1 … применение процедуры P1

END;

PROCEDURE P1; описание процедуры P1

BEGIN

P2 применение процедуры P2

END;

BEGIN .. ..

P1 .. .. применение процедуры Р1

END.

Но эта схема противоречит упомянутому принципу, так как применение процедуры Р1 предшествует ее описанию. В Паскале существует способ справиться с этой ситуацией. Достаточно полный заголовок процедуры Р1 скопировать в любое место выше описания процедуры Р2, снабдив его так называемой директивой FORWARD. Программа примет такой вид:

PROCEDURE Р1, forward; опережающее описание процедуры Р1

PROCEDURE Р2; описание процедуры Р2

BEGIN....

Р1 ..... применение процедуры Р1

END;

PROCEDURE Р1; описание процедуры Р1

BEGIN ....

Р2 ..... применение процедуры Р2

END;

BEGIN .....

Р1 .... применение процедуры Р1

END.

10.7. Управление компьютером с клавиатуры. Функции ReadKey и KeyPressed

Попробуйте запустить программу, которая долго делает свое дело, не обращая на вас внимания. Например, такую:

BEGIN repeat WriteLn('A нам все равно!') until 2>3 END.

Вы сидите перед компьютером и ждете, когда он закончит печатать свой текст. А он никогда не закончит.

Только когда вы, удерживая нажатой клавишу Ctrl, щелкнете по клавише Break, программа прервет свою работу.

Пока программы работают, они не реагируют на клавиатуру, если вы об этом специально не позаботились. А чтобы позаботиться, вы должны включить в них специальные функции ReadKey и KeyPressed из модуля CRT. О смысле функций вообще мы поговорим в разделе 13.2

Дополним нашу программу парой строк:

USES CRT;

BEGIN

repeat

If KeyPressed then WriteLn('Хозяин нажал клавишу!')

else WriteLn('A нам все равно!')

until 2>3

END.

Выражение if KeyPressed then можно перевести как "если нажата клавиша, то". Встретив это выражение, Паскаль проверяет, была ли нажата клавиша на клавиатуре. Когда вы запустите эту программу, она будет бесконечно печатать А нам все равно! Но как только вы щелкнете по какой-нибудь клавише, программа станет бесконечно печатать Хозяин нажал клавишу!

Если функция KeyPressed просто реагирует на то, была ли нажата какая-нибудь клавиша, то функция ReadKey сообщает, какая именно клавиша была нажата.

Вот программа, которая бесконечно печатает текст А нам все равно! и одновременно непрерывно ждет нажатия на клавиши, и, как только клавиша нажата, однократно докладывает, была ли нажата клавиша w или другая клавиша, после чего продолжает печатать А нам все равно! Если мы захотим, чтобы программа закончила работу, мы должны нажать на клавишу q.

USES CRT;

VAR klavisha :Char;

BEGIN

repeat

Delay (1000);

{иначе программа печатает слишком быстро}

WriteLn('A нам все равно!');

if KeyPressed then begin

klavisha:= ReadKey;

if klavisha='w' then WriteLn('Haжaтa клавиша w')

else WriteLn('Haжaтa другая клавиша')

end {if}

until klavisha='q'

END.

Программа доберется до строки klavisha:= ReadKey только в случае, если будет нажата какая-нибудь клавиша. Функция ReadKey определяет, какой символ был на нажатой клавише, и присваивает его значение переменной, которую мы придумали - klavisha. С этого момента вы можете как хотите анализировать эту переменную и в зависимости от ее значения управлять работой компьютера.

Наша программа будет бесконечно печатать А нам все равно!, а при каждом нажатии на клавишу будет однократно сообщать Нажата клавиша w или Нажата другая клавиша. Почему однократно, а не бесконечно? Грубо это можно объяснить тем, что после выполнения функции ReadKey Паскаль не помнит, что на клавиатуре была нажата клавиша.

Вы спросите: "А зачем здесь вообще нужна строка if KeyPressed then?" Дело в том, что если перед выполнением функции ReadKey клавишу на клавиатуре не нажать, то функция ReadKey останавливает программу и заставляет ее ждать нажатия на клавишу, а после нажатия программа продолжает работу. Если вам в вашей программе паузы не нужны, то вам придется использовать KeyPressed.

Функция ReadKey напоминает процедуру ReadLn. Однако у нее есть интересное отличие: при вводе символов по процедуре ReadLn они появляются на экране, а при вводе символа по функции ReadKey - нет. Благодаря этому свойству с помощью ReadKey можно организовать "секретный ввод" информации в компьютер - человек, стоящий у вас за спиной и видящий экран монитора, но не видящий ваших пальцев, никогда не догадается, на какие клавиши вы нажимаете.

Подробнее о механизме действия ReadKey и KeyPressed - в разделе 10.8.

Задача "Пароль на программу". Пусть вы сделали какую-нибудь интересную программу и не хотите, чтобы ее кто-то запускал. Для этого сделаем так, чтобы программа начинала свою работу с предложения пользователю ввести пароль. Если пользователь набрал правильный пароль, то программа нормально продолжает свою работу, в противном случае прерывается.

Пусть ваш пароль - typ. Тогда для решения задачи вам достаточно вставить в начало вашей программы следующий фрагмент:

WriteLn('Введите, пожалуйста, пароль');

Simvol1:=ReadKey;

Simvol2:=ReadKey;

Simvol3:=ReadKey;

if NOT ((Simvol1='t') AND (Simvol2='y') AND (Simvol3='p')) then Halt;

{Продолжение программы}

Вы скажете: "Кто-то перед запуском моей программы посмотрит в ее текст и сразу же увидит пароль". Совершенно верно. Чтобы текст программы не был виден, преобразуйте ее в исполнимый файл с расширением "ехе" (см. часть 4).

Задание 96

"Светофор". Нарисуйте светофор: прямоугольник и 3 окружности. При нажатии нужной клавиши светофор должен загораться определенным светом.

Задание 97

"Зенитка". Вверху справа налево медленно движется вражеский самолет (эллипс). В подходящий момент вы нажатием любой клавиши запускаете снизу вверх зенитный снаряд (другой эллипс).