Модульная структура программы
Подключение модулей
Для того чтобы подключить к программе какой-либо модуль, необходимо сразу после заголовка программы поместить следующую строку:
uses <имя_модуля>;
Если подключаемых модулей несколько, эта строка примет вид:
uses <имя_модуля_1>,...,<имя_модуля_N>;
Впрочем, совершенно не обязательно указывать имена всех модулей, так или иначе фигурирующих в программе. Достаточно указать имена лишь тех, к которым она будет обращаться непосредственно. А к каждому модулю, подключенному к головной программе, в случае необходимости можно подключить другие модули - и т. д.
Все константы, типы данных, переменные, процедуры и функции, описанные в каком-либо модуле, после его подключения к основной программе (или к другому модулю ) становятся доступными этой программе (или модулю ) без дополнительных объявлений.
Например, вы можете пользоваться функцией abs(), не объявляя и не описывая ее, поскольку эта функция включена в состав стандартного модуля System, автоматически подключаемого к любой программе на языке Pascal. Если же вы захотите очистить экран монитора перед выдачей результатов, вам придется подключить к вашей программе модуль crt и воспользоваться содержащейся в нем процедурой clrscr (см. лекцию 14).
Создание модульной программы
Перейдем теперь к детальному изучению структуры модулей и правил их создания и использования.
Структура модуля
В состав модуля входят четыре секции (любая из них может быть пустой, но ее заголовок все равно обязан присутствовать):
unit <имя_модуля>; interface {секция внешних связей} implementation {секция реализаций} begin {секция инициализации} end.
Разберем каждую из этих секций отдельно.
Название
В отличие от заголовка программы ( program <имя_программы>; ), который может и отсутствовать, заголовок модуля ( unit <имя_модуля>; ) обязан присутствовать всегда.
Кроме того, очень полезно давать модулям и содержащим их файлам одинаковые имена. Иначе говоря, модуль с именем modul_1 желательно разместить в файле с именем modul_1.pas, и т.п.
Секция внешних связей
Эта секция содержит объявления тех типов данных, констант, переменных, подпрограмм и т.п., которые должны быть видны вне модуля.
Если для объявления какого-либо объекта нужны сведения об объекте, объявленном в другом модуле, то имя этого модуля необходимо указать в этой же секции:
interface [uses <список_вспомогательных_модулей>;] [const <список_внешних_констант>;] [type <список_внешних_типов_данных>;] [var <список_внешних_переменных>;] [procedure <объявление_внешней_процедуры>;] [function <объявление_внешней_функции>;]
Например, пусть у нас есть два модуля: mod_const, содержащий описания базовых констант и типов данных, и mod1, использующий эти описания (мы приводим только секции внешних связей ):
unit mod_const; interface const sto = 100; type one_to_sto = 1..sto; ... unit mod1; interface uses mod_const; const dvesti = 2*sto; type massiv = array[1..dvesti] of byte; var a: massiv; b: one_to_sto; function min(x,y:one_to_sto):one_to_sto; ...
Теперь, если в каком-либо третьем модуле встретится строка
uses mod1;
то внутри этого третьего модуля можно будет использовать (без дополнительных объявлений) тип massiv, переменные a и b, а также функцию min. Необходимо отметить, что использовать константу sto третий модуль не сможет, поскольку в нем не было указано
uses mod_const;
Если в секциях связей нескольких модулей были определены константы или переменные с одинаковыми именами, но с разными значениями, то путаницы позволит избежать уже знакомый нам прием: указание имени модуля перед идентификатором:
<имя_модуля>.<идентификатор>
Если имя модуля не указано, то идентификатор считается принадлежащим текущему модулю. И только если в текущем модуле этот идентификатор не был объявлен, то начинается поиск в подключенных модулях.
Например, если модульная программа имеет структуру, изображенную на рис. 13.1, то таблица доступности переменных будет выглядеть так:
Связи | Способ обращения к одноименным переменным | |||||||
program prg; | uses A,B,C; | p | a.p | b.p | c.p | не видна | не видна | |
unit A; | uses C,D,F; | не видна | p | не видна | c.p | d.p | f.p | |
unit B; | uses F; | не видна | не видна | p | не видна | не видна | f.p | |
unit C; | - | не видна | не видна | не видна | p | не видна | не видна | |
unit D; | - | не видна | не видна | не видна | не видна | p | не видна | |
unit F; | - | не видна | не видна | не видна | не видна | не видна | p |
Замечание: В секциях связей не допускается рекурсивное использование модулями друг друга. Иными словами, нельзя одновременно написать
unit mod_1; interface uses mod_2; ... unit mod_2; interface uses mod_1; ...