Скачиваний:
308
Добавлен:
01.05.2014
Размер:
3.67 Mб
Скачать
      1. Порядок описания переменных, процедур и других конструкций Паскаля

Если вы помните (0.6), перед тем, как выполниться, программа на Паскале компилируется на машинный язык. При компиляции она просматривается сверху вниз, при этом Паскаль строго следит, чтобы ни одна переменная, процедура или другая конструкция не была в тексте программы применена выше, чем описана. Что имеется в виду?

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

Посмотрим на нашу программу. Мы мудро поместили раздел VAR на самый верх программы. А если бы мы поместили его, скажем, между описаниями процедур MusicиFlying_Saucer, то например, переменнаяiбыла бы применена в тексте (в операторе for расположенной выше процедурыLandscape) выше, чем описана, на что Паскаль среагировал бы сообщением об ошибке. То же касается и переменнойy_goriz, которая бы в этом случае была применена два раза ниже описания (в операторахrepeatиy_goriz:=240), но один раз - выше (в оператореLine(0, y_goriz, 640, y_goriz)). Не путайте - в данном конкретном случае важен не порядок исполнения операторов в процессе выполнения программы, о котором мы заранее часто и сказать ничего не можем, а примитивный порядок записи описаний и операторов в тексте программы.

Те же рассуждения применимы и к процедурам и другим конструкциям. Так, описание процедуры Treeни в коем случае нельзя было помещать ниже описания процедурыLandscape, так как в процедуреLandscape процедураTreeприменяется, причем три раза.

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

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

BEGIN….

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

END;

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

BEGIN .....

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

END;

begin.....

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

end.

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

ProcedureP1; forward; опережающее описание процедуры P1

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

BEGIN….

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

END;

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

BEGIN .....

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

END;

begin.....

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

end.

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

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

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

Вы сидите перед компьютером и ждете, когда он закончит печатать свой текст. А он никогда не закончит. Вы принимаетесь стучать по клавишам, надеясь, что это прервет бессмысленный цикл. Бесполезно.

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

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

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

USESCRT;

BEGIN

repeat

if KeyPressed then WriteLn(‘Хозяин нажал клавишу!’)

elseWriteLn(‘А нам все равно!’)

until2>3

END.

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

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

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

USESCRT;

VARklavisha : Char;

BEGIN

repeat

Delay (1000); {иначе программа печатает слишком быстро}

WriteLn(‘А нам все равно!’);

if KeyPressed then begin

klavisha:= ReadKey;

if klavisha=’w’ then WriteLn(‘Нажата клавиша w’)

elseWriteLn(‘Нажата другая клавиша’)

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 см. в следующем параграфе.

Задача “Пароль на программу”.

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

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

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

Simvol1:= ReadKey;

Simvol2:= ReadKey;

Simvol3:= ReadKey;

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

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

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

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

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