Глава 15. МОДУЛИ
Наличие модулей в Turbo Pascal позволяет программировать и отлаживать программу по частям,
создавать библиотеки подпрограмм и данных, воспользоваться возможностями стандартных модулей,
практически неограниченно увеличивать кодовую (содержащую коды команд) часть программы.
Модуль состоит из следующих частей: заголовок модуля; интерфейс модуля; исполнительная часть
модуля; секция инициализации.
Все разделы модуля, за исключением секции инициализации, являются обязательными. Обязательна
также указанная последовательность разделов.
15.1. Заголовок модуля
Заголовок модуля состоит из зарезервированного слова unit и идентификатора. Идентификатор
модуля должен быть уникальным. Пример заголовка:
unit MyModule;
Модуль должен быть помещен в файл, имя которого совпадает с именем модуля, а его расширение
должно быть .PAS.
15.2. Интерфейс модуля
Через интерфейс осуществляется взаимодействие основной программы с модулем (модуля с модулем).
В интерфейсе указываются константы, типы, переменные, процедуры и функции, которые могут быть
использованы основной программой (модулем) при вызове этого модуля.
Интерфейс начинается словом interface. Далее после слова uses указываются имена модулей,
которые используются данным модулем (необязательная часть).
После этого могут быть: раздел объявления констант, раздел объявления типов, раздел
объявления переменных, раздел объявления процедур и функций. Объявление процедуры может
содержать директиву inline. В разделе объявления процедур и функций указываются лишь
заголовки подпрограмм (за исключением тех подпрограмм, которые используют директиву inline).
Сами подпрограммы приводятся в исполнительной части.
В интерфейсах различных модулей недопустимо циклическое обращение друг к другу, т. к.
компилятор в этом случае не может установить связей.
15.3. Исполнительная часть модуля
Исполнительная часть включает все подпрограммы модуля. Она может также включать локальные
метки, константы, типы и переменные.
Исполнительная часть начинается словом implementation. Затем после слова uses указываются
имена модулей, которые используются подпрограммами данной исполнительной части (этот раздел
необязателен). Если какой-то модуль уже указан в интерфейсе модуля, то в исполнительной части
его повторять не следует. Далее могут быть: раздел объявления меток, раздел объявления
локальных констант, раздел объявления локальных типов, раздел объявления локальных переменных.
Затем идут описания подпрограмм модуля. При описании подпрограмм допустимо использовать
сокращенные заголовки, как и в случае использования директивы forward (см. п. 10.5.1).
В отличие от интерфейсов модулей в исполнительных частях модулей допустимо циклическое
обращение друг к другу, т. к. все равно взаимодействие осуществляется через интерфейсы, и
здесь не возникает проблемы с установлением необходимых связей.
15.4. Секция инициализации
В некоторых случаях перед обращением к модулю следует провести его инициализацию (например,
установить связь с теми или иными файлами с помощью процедуры Assign, инициализировать
какие-то переменные и т. д.). Необходимые действия можно выполнить в секции инициализации
модуля. Эта секция начинается словом begin, после которого идут исполняемые операторы, а
затем помещается слово end. (с точкой), например:
begin
Assign(Fl, 'FILE1.DAT')
end.
Следует иметь в виду, что операторы секции инициализации выполняются единственный раз в
момент запуска программы.
Пример использования секции инициализации приведен в п. 16.4.34 и в приложении Г.
Если инициализация модуля не нужна, то в секции помещается лишь слово end. (с точкой).
15.5. Использование модуля в основной программе
Чтобы использовать подпрограммы, константы, типы, переменные, описанные в интерфейсе модуля,
в основной программе следует записать слово uses, после которого указать имя (имена) модуля
(модулей). После этого в основной программе можно использовать идентификаторы, указанные в
интерфейсах перечисленных модулей.
Пример. Программа, меняющая в массиве максимальное и минимальное числа.
program EXAMPLE26; {заголовок программы}
uses Unitl, Unit2; {используемые модули}
var i: Integer;
begin
Change(Arr); {процедура замены в Unit1, массив Arr - в Unit2}
for i := 1 to N do {N - в Unit2}
WriteLn(Arr[i])
end.
{модули, расположенные в других файлах}
unit Unitl; {модуль с основной подпрограммой}
interface {интерфейс первого модуля}
uses Unit2; {использование модуля с параметрами}
procedure Change(var Arr: Mass); {заголовок процедуры}
implementation {исполнительная часть}
uses Unit3; {использование модуля с вспомогательной подпрограммой}
procedure Change; {сокращенный заголовок}
var Max, Min, i: Integer;
begin
Max := 1;
Min := 1;
for i := 1 to N do {N - в Unit2 }
begin
if Arr[i] > Arr[Max]
then Max := i;
if Arr[i] < Arr[Min]
then Min := i
end;
Swap(Arr[Max], Arr[Min]) {замена местами макс.и мин.чисел,
процедура в Unit3}
end
end. {конец Unitl}
unit Unit2; {модуль с параметрами}
interface {интерфейс второго модуля}
const
N = 5; {число элементов}
type
Mass = array[l..N] of Real; {тип массива}
const
Arr: Mass = (0.5, -2.0, 1.0, 3.5, 7.0); {типизированная константа}
implementation {исполнительная часть}
end. {конец UNIT2}
unit Unit3; {модуль с вспомогательной подпрограммой}
interface {интерфейс третьего модуля}
procedure Swap(var X, Y: Real);
implementation {исполнительная часть}
procedure Swap(var X, Y: Real); {перемещение двух чисел}
var Z: Real;
begin
Z := X;
X := Y;
Y := Z
end
end. {конец UNIT3}
15.6. Использование идентификаторов элементов модуля
Как правило, идентификаторы объектов модуля используются в основной программе (или другом
модуле) обычным образом. Однако может оказаться, что используемый идентификатор элемента
модуля совпадает с идентификатором использующей его программы. Чтобы различить их, при
обращении к элементу модуля указывается имя модуля, а затем через точку - идентификатор
объекта (аналогично использованию полей записи).
Пример.
program EXAMPLE27 ;
uses Unit1;
var
Result, X: Real;
begin
Read(X); {чтение переменной программы}
Read(Unitl.X); {чтение переменной модуля}
Result := X {переменная программы}
+ Unitl.X {переменная модуля}
end.
unit Unit1;
interface
var
X: Real; {переменная модуля}
implementation
end.