Модуль является программной единицей для хранения элементов, которые можно использовать в тех или иных программах. Такими элементами могут быть типы (включая объекты), константы, переменные и подпрограммы. Если все, что было написано в программе, полностью входит в скомпилированный файл программы, то из модуля в скомпилированную программу попадают только те части, которые необходимы данной программе. Поэтому модуль выступает как библиотека, которую можно употреблять во многих программах, и каждая из них берет только то, что ей требуется. Наличие модулей в Turbo Pascal позволяет программировать и отлаживать программу по частям, создавать библиотеки подпрограмм и данных, воспользоваться возможностями стандартных модулей, практически неограниченно увеличивать кодовую (содержащую коды команд) часть программы.
Все модули можно разбить на две группы:Через интерфейс осуществляется взаимодействие основной программы с модулем (модуля с модулем). В интерфейсе указываются константы, типы, переменные, процедуры и функции, которые могут быть использованы основной программой (модулем) при вызове этого модуля.
Интерфейс начинается словом interface и может содержать следующие разделы:Завершается интерфейс началом исполнительной части.
Раздел объявления используемых модулей интерфейсной части модуля точно такой же, как у программы, а параметры модулей, перечисленных здесь, могут использоваться во всех частях модуля, а не только в интерфейсной части.
Если один модуль обращается к интерфейсной части другого, который в своей интерфейсной части обращается к третьему модулю и т. д., наконец, последний модуль использует первый модуль (так называемое циклическое использование модулей), то такая ситуация недопустима из-за того, что компилятор в этом случае не сможет установить необходимые связи.
Все разделы интерфейсной части, кроме раздела объявления используемых модулей, могут идти в любой последовательности; можно создавать несколько однотипных разделов.
В разделе объявления процедур и функций указываются лишь заголовки подпрограмм (за исключением тех подпрограмм, которые используют директиву inline, которая здесь допустима). Сами подпрограммы приводятся в исполнительной части модуля.
Исполнительная часть включает все подпрограммы модуля. Она может также включать локальные метки, константы, типы и переменные, недоступные для других программных единиц (естественно, и для интерфейса самого модуля).
Начинается исполнительная часть словом implementation, а завершается либо началом секции инициализации, если она есть, либо словом end. (с точкой).
Исполнительная часть - "внутренняя кухня" модуля, где протекают процессы, о которых не надо "знать" другим программным единицам. Она может содержать следующие разделы:В разделе объявления используемых модулей исполнительной части перечисляются модули, параметры которых могут употребляться в модуле всюду за исключением интерфейсной части (чаще всего так и бывает). В исполнительной части допускается циклическое применение модулей (см. 15.2), поэтому по мере возможности именно здесь следует объявлять модули. Если какой-то модуль объявлен в интерфейсной части, то в исполнительной части его объявлять не следует. В остальном раздел объявления используемых модулей исполнительной части такой те, как и в интерфейсной части.
Все разделы исполнительной части, кроме раздела объявления модулей, могут идти в любой последовательности; можно создавать несколько однотипных разделов.
При описании процедур и функций в исполнительной части допустимо записывать их сокращенные заголовки, как в случае директивы forward (см. 10.5.1). Если же здесь записываются полные заголовки, они должны быть полностью идентичны заголовкам в интерфейсной части.
begin Assign(F, TILE1.DAT) end.
Следует иметь в виду, что операторы секции инициализации выполняются единственный раз в момент запуска программы.
Пример использования секции инициализации приведен в 16.4.34 и в приложении Д (с. 702-708). Если инициализация модуля не нужна, то в секции помещается лишь слово end. (с точкой).
Чтобы использовать подпрограммы, константы, типы, переменные, описанные в интерфейсе модуля, в основной программе следует поместить раздел объявления используемых модулей. Раздел состоит из одного предложения и начинается зарезервированным словом uses, после указываются через запятую имена модулей. После этого в основной программе можно использовать идентификаторы, указанные в интерфейсах перечисленных модулей.
Пример. Программа, меняющая в массиве максимальное и минимальное числаprogram EXAMPLE45; {Заголовок программы} uses Unit1, Unit2; {Используемые модули) var i: Integer, begin Change(Arr); {Процедура замены в Unitl, массив 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 UnitS; {Использование модуля со вспомогательной подпрограммой} 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[1..N] of Real; (Тип массива} const Arr: Mass = (0.5, -2.0, 1.0, 3.5, 7.0); {Типизированная константа} implementation {исполнительная часть/ end. {Конец UNIT2} unit UnitS; {Модуль со вспомогательной подпрограммой} 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. {Конец UNITS}
Как правило, идентификаторы объектов модуля используются в основной программе (или другом модуле) обычным образом. Однако может оказаться, что используемый идентификатор элемента модуля совпадает с идентификатором использующей его программы. Чтобы различить их, при обращении к элементу модуля используется его квалификатор (см. 6.4), в качестве которого выступает имя модуля.
Пример. Использование одноименных идентификаторовprogram EXAMPLE46; {Программа} uses Unitl; var Result, X: Real; begin Read(X); (Чтение переменной программы} Read(Unitl.X); {Чтение переменной модуля} Result := X {Переменная программы) + Unit1 .X; {Переменная модуля} end. unit Unit1; {Модуль} interface var X: Real; {Переменная модуля} implementation end.