TURBO PASCAL

Новости       

Программы

Turbo Pascal

Игры

Документация

"Странности"

FAQ

Ссылки

Благодарности 

Гостевая книга

Спонсор

От автора

Глава 10. Программы и модули

·        Синтаксис программ

·        Заголовок программы

·        Оператор uses

·        Синтаксис модулей

·        Заголовок модуля

·        Интерфейсная секция

·        Секция реализации

·        Секция инициализации

·        Косвенные ссылки на модули

·        Перекрестные ссылки на модули

·        Совместное использование описаний

 

Синтаксис программ

Программа в Borland Pascal состоит из заголовка программы, необязательного оператора uses и основного блока.

Возврат в начало

 

 

Заголовок программы

Заголовок программы определяет имя программы и ее параметры.

Если заголовок программы присутствует, он является чисто де­коративной деталью и компилятор его игнорирует.

Возврат в начало

 

 

Оператор uses

Оператор uses идентифицирует все модули, используемые прог­раммой, включая непосредственно используемые модули и модули, ис­пользуемые этими модулями.

Модуль System всегда используется автоматически. Для под­держки таких средств, как файловый ввод-вывод, обработка строк, операции с плавающей запятой, динамическое распределение памяти и других этот модуль реализует весь нижний уровень, а также обслу­живающие фоновые программы.

Паскаль, в свою очередь, обслуживает многие стандартные мо­дули, такие, как Dos и Crt. Это не происходит автоматически: вы должны обязательно включить их в оператор uses. Например:

uses Dos,Crt;  теперь могут быть доступны средства модулей

Dos и Crt

Чтобы найти файл, содержащий скомпилированный модуль, компи­лятор усекает указанное в операторе uses имя модуля до первых восьми файлов и добавляет расширение файла. Если целевой платфор­мой является DOS, расширением будет .TPU. Если целевая платформа

- Windows, то расширением файла будет .TPW. Если целевой платфор­мой является защищенный режим DOS, то расширением файла будет .TPP. Хотя имена файлов усекаются, в операторе uses должен указы­ваться полный идентификатор модуля.

Возврат в начало

 

 

Синтаксис модулей

Модули являются основой модульного программирования. Они ис­пользуются для создания библиотек, которые могут включаться в различные программы (при этом становится необязательным иметь в наличии исходный код), а большие программы могут подразделяться на логически связанные модули.

Возврат в начало

 

 

Заголовок модуля

В заголовке модуля определяется имя модуля.

Имя модуля используется при ссылке на модуль в предложении использования. Это имя должно быть уникальным, так как два модуля с одним именем не могут одновременно использоваться.

Имя исходного файла модуля и двоичного файла должны совпа­дать с идентификатором модуля, усеченным до первых 8 символов. Если это не так, то компилятор не сможет найти исходный и/или двоичный файл при компиляции использующей этот модуль программы.

Возврат в начало

 

 

Интерфейсная секция

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

В том случае, если процедура или функция является процедурой или функцией типа inline, в интерфейсной секции содержится только список заголовков процедур или функций. Модуль процедуры или функции следует дальше в секции реализации. Заметим, что заголо­вок процедуры или функции может дублироваться и быть здесь таким же, как в интерфейсной секции. Вам не нужно задавать здесь список формальных параметров, но если вы это сделали и если описание в интерфейсной секции и секции реализации не совпадают, то компиля­тор во время компиляции выдаст сообщение об ошибке.

Возврат в начало

 

 

Секция реализации

В секции реализации определяются модули всех глобальных про­цедур или функций. В ней также описываются константы, переменные, процедуры и функции, являющиеся локальными, то есть недоступными основной программе.

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

Допускается дублирование заголовков процедур и функций из интерфейсной части. Вам не нужно при этом задавать список фор­мальных параметров, но если вы это делаете, компилятор на этапе компиляции в случае несовпадения описаний в интерфейсной части и секции реализации будет выдавать сообщение об ошибке.

Возврат в начало

 

 

Секция инициализации

Секция инициализации является последней секцией модуля. Она может состоять либо из зарезервированного слова end (в этом слу­чае модуль не содержит кода инициализации), либо из операторной части, которая должна выполняться для инициализации модуля.

Секции инициализации модулей, которые используются програм­мой, выполняются в том же порядке, в каком модули указаны в опе­раторе uses.

Возврат в начало

 

 

Косвенные ссылки на модули

В операторе uses в основной программе должны содержаться имена всех модулей, непосредственно или косвенно используемых ос­новной программой. Рассмотрим следующий пример:

Program Prog; uses Unit1, Unit2 const a = b; begin end. end.

unit Unit2; interface uses Unit1; const b = c; implementation end.

unit Unit1; interface const c = 1; implementation const d = 2; end;

В данном примере Unit12 непосредственно зависит от Unit1, а Prog непосредственно зависит от Unit2. Кроме того, Prog зависит косвенно от Unit1 (через Unit1), хотя ни один из описанных в Unit1 идентификаторов в Prog не доступен.

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

Когда в интерфейсную часть модуля вносятся изменения, другие модули, использующие этот модуль, должны быть заново скомпилиро­ваны. При использовании команд Make или Build компилятор делает это автоматически. Однако, если изменения коснулись только секции реализации или секции инициализации, то другие модули, в которых используется этот модуль, перекомпилировать не нужно. В предыду­щем примере, если интерфейсная часть модуля Unit1 изменилась (например, с = 2), то модуль Unit2 нужно перекомпилировать. Изме­нение же секции реализации (например, d = 1) не требует переком­пиляции Unit2.

При компиляции модуля в Borland Pascal на основе контрольной суммы интерфейсной секции вычисляется номер версии модуля. В пре­дыдущем примере при компиляции модуля Unit2 в скомпилированной версии модуля Unit2 сохраняется номер версии модуля Unit1. При компиляции основной программы номер версии модуля Unit1 сравнива­ется с номером версии, сохраненным в модуле Unit2. Если номера версий не совпадают, что свидетельствует об изменении в интер­фейсной части модуля Unit1 со времени последней компиляции модуля Unit2, компилятор, в зависимости от режима компиляции, выдает со­общение об ошибке или перекомпилирует модуль Unit2 (в зависимости от режима компиляции).

Возврат в начало

 

 

Перекрестные ссылки на модули

Размещение в секции реализации оператора uses позволяет "скрыть" внутренние детали модуля, поскольку используемые в сек­ции реализации модули оказываются "невидимыми" для того, кто этот модуль использует. Более важным, однако, является то, что это позволяет вам строить взаимозависимые модули.

В следующей программе показаны два модуля, которые "исполь­зуют" друг друга. Основная программа Circular использует модуль с именем Display. Модуль Display содержит в своей интерфейсной сек­ции одну программу WriteXY, которая имеет три параметра: пару ко­ординат (x,y) и сообщение для вывода на экран. WriteXY перемещает курсор в точку (x,y) и выводит там сообщение. В противном случае она вызывает простую программу обработки ошибки.

Пока мы не видим здесь ничего интересного: процедура WriteXY просто используется вместо процедуры Write. Однако далее, когда программа обработки ошибки будет выводить сообщение на экран, на­чинаются перекрестные ссылки (ведь при этом она снова использует WriteXY). Таким образом, мы имеем процедуру WriteXY, вызывающую процедуру обработки ошибки SwapError, которая в свою очередь вы­зывает WriteXY для вывода сообщения на экран. Если у вас уже от всего этого закружилась голова, не беда. Давайте рассмотрим ис­ходный код в примере и увидим, что все это не столь уж запутано.

Основная программа Circular очищает экран и выполняет три обращения к процедуре WriteXY:

program Circular;

 выводит текст, используя WriteXY

uses

WinCrt, Display;

begin

ClrScr;

WriteXY(1, 1, 'Левый верхний угол экрана');

WriteXY(100, 100, 'За пределами экрана');

WriteXY(81 - Lenght('Снова в экран..'), 15,

'Снова в экран..');

end.

Взгляните на координаты (x,y) при втором обращении к проце­дуре WriteXY. В точке с координатами (100,100) на 80х25-символь­ном экране вывести текст невозможно. Давайте теперь посмотрим, как работает процедура WriteXY. Далее приведен текст исходного кода модуля Display, в котором содержится процедура WriteXY. Если координаты (x,y) являются допустимыми, она выводит на экран сооб­щение. В противном случае она выводит сообщение об ошибке.

unit Display;

 содержит простую программу вывода информации на экран

interface

procedure WriteXY(X,Y : integer, Message : string);

implementation

uses

Crt, Error;

procedure WriteXY(X,Y : integer, Message : string);

begin

if (X in [1..80] and Y in [1..25] then

begin

Goto(X,Y);

Write(Message); end; else

ShowError('Неверные координаты в процедуре WriteXY'); end;

end.

Процедура ShowError, вызываемая в процедуре WriteXY, показа­на в приведенном далее исходном коде модуля Error. Она всегда вы­водит сообщение об ошибке на 25-й строке экрана.

unit Error;

 содержит простую программу сообщения об ошибке

interface

procedure ShowError(ErrMsg : string);

implementation

uses

Display;

procedure ShowError(ErrMsg :string);

begin

WriteXY(1,25, 'Ошибка: '+ ErrMsg); end;

end.

Обратите внимание, что операторы uses в секции реализации обоих модулей (Display и Error) ссылаются друг на друга. Эти два модуля могут ссылаться друг на друга в секции реализации благода­ря тому, что Borland Pascal может для обеих модулей выполнять полную компиляцию интерфейсных секций. Другими словами, компиля­тор воспринимает ссылку на частично скомпилированный модуль A в секции реализации модуля В, если интерфейсные секции модуля A и модуля В не зависят друг от друга (и, следовательно, строго соб­людаются правила Паскаля, касающиеся порядка описания).

В случае взаимозависимости интерфейсных секций модулей вы получите ошибку из-за перекрестных ссылок.

Возврат в начало

 

 

Совместное использование описаний

Можно модифицировать процедуру WriteXY таким образом, чтобы она воспринимала дополнительный параметр, задающий прямоугольное окно на экране:

procedure WriteXY(SomeWindow : WindRec;

X, Y :                                                  integer;

Message :                                            string);

procedure ShowError(Somewindow : WindRec; ErrMsg : string);

Нужно учитывать, что две процедуры находятся в разных моду­лях. Даже если вы описываете WindData в интерфейсной секции одно­го модуля, то нет такого допустимого способа, с помощью которого это описание могло бы быть доступно в другом модуле. Решение сос­тоит в том, чтобы описать третий модуль, в котором содержится только определение записи WindRec:

unit WindData;

interface

type

WindRec = record

X1, Y1, X2, Y2 : integer;

ForeColor,

BackColor                                     : byte;

Active                                            : boolean;

end;

implementation

end.

В добавление к тому, что модификация кода процедур WriteXY и ShowError позволяет использовать новый параметр, в интерфейсной секции модулей Display и Error теперь может использоваться WindData. Это допустимо, так как модуль WindData не зависит от своего оператора uses, а модули Display и Error ссылаются друг на друга только в соответствующих секциях реализации.

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

 

Возврат в начало

 

 

На первую страницу

Rambler's Top100 PROext: Top 1000
Rambler's Top100

(с) Все права защищены.

По всем интересующим вопросам прошу писать электронный адрес

Hosted by uCoz