Секция реализации
Этот раздел модуля содержит реализации всех подпрограмм, которые были объявлены в секции внешних связей. Здесь объявление подпрограммы оторвано от ее описания. Однако ключевое слово forward здесь является излишним.
Кроме того, в этой же секции объявляются и описываются внутренние (невидимые вне модуля) метки, константы, типы данных, переменные и подпрограммы.
implementation
[uses <список_вспомогательных_модулей>;]
[const <список_внутренних_констант>;]
[type <список_внутренних_типов_данных>;]
[var <список_внутренних_переменных>;]
[procedure <описание_внешней_процедуры>;]
[function <описание_внешней_функции>;]
[procedure <объявление_и_описание_внутренней_процедуры>;]
[function <объявление_и_описание_внутренней_функции>;]
В отличие от секции внешних связей, секции реализации из различных модулей могут использовать друг друга рекурсивно. Иными словами, совершенно законной будет запись, например, такого вида:
unit mod_1;
interface
...
implementation
uses mod_2;
...
unit mod_2;
interface
...
implementation
uses mod_1;
...
Пример рекурсии при обращении к модулям. Смысл рекурсии здесь состоит в том, что вывод некоторого сообщения на заданную позицию экрана при помощи процедуры message, содержащейся в модуле mod_1, может сгенерировать ошибку, сообщение о которой (процедура _error из модуля mod_2) снова задействует процедуру message - но уже с другими параметрами.
unit mod_1;
interface
procedure message(x,y: byte; msg: string);
implementation
uses mod_2, crt;
procedure message;
begin if(x in [1..80-length(msg)]and(y in [1..25])
then begin gotoxy(x,y); {позиционирование курсора}
write(msg)
end
else _error('Сообщение не входит в экран')
{вызов процедуры из модуля mod_2}
end;
end.
unit mod_2;
interface
procedure _error(msg:string);
implementation
uses mod_1;
procedure _error;
begin message(1,25,msg); {вызов процедуры из модуля mod_1}
end;
end.
Секция инициализации
Секции инициализации всех подключенных к программе модулей исполняются один раз, перед началом работы основной программы:
begin
<произвольные_операторы>
end.
Если сразу несколько модулей содержат секции инициализации, то порядок выполнения этих секций будет следующим:
-
Если модуль А подключает модуль В (не важно, в какой именно секции), то секция инициализации модуля В будет выполнена раньше, чем секция инициализации, содержащаяся в модуле А.
-
Если два модуля В и С подключаются на одном уровне (считаются равноправными), то их секции инициализации будут выполнены в том порядке, в каком имена этих модулей указаны в разделе uses.
Если каждый модуль из тех, что составляют программу на рис. 13.1, имеет непустую секцию инициализации, то эти секции будут выполнены в следующей последовательности: C, D, F, A, B. Если же к головной программе модули будут подключены в другом порядке, например:
uses B,A,C;
то секции инициализации будут выполняться в другой последовательности:
F, B, C, D, A.
Замечание: Если секция инициализации в модуле отсутствует (а так чаще всего и бывает), то ключевое слово begin указывать не обязательно. Однако end. обязан закрывать текст модуля в любом случае.
Взаимодействие модулей
Если необходимо сделать так, чтобы несколько равноправных модулей имели доступ к одним и тем же переменным, константам и т.п., то наиболее практичным способом является введение дополнительного модуля, в котором будут объявлены все глобальные переменные, константы и типы данных. Секция реализации у этого нового модуля будет пустой.
Рисунок. 13.2 - Использование модуля определений
Компиляция модулей
Исходные тексты модулей хранятся в файлах с расширением .pas, а результаты их компиляции - в файлах с расширением .tpu.
Существует три варианта превращения модульной программы в исполняемый код.
-
Все подключаемые модули должны быть откомпилированы заранее; после этого можно компилировать головную программу, используя команду Compile | Compile главного меню или нажатие клавиш ALT+F9. Если вы случайно забыли откомпилировать какой-либо модуль (соответствующий файл с расширением .tpu отсутствует), то компилятор выдаст сообщение о недостающем файле. Если в текст какого-либо модуля были внесены изменения, но перекомпиляция не производилась (изменился файл .pas, но файл .tpu остался прежним), то в исполняемый код программы будет включена старая версия этого модуля.
-
Компилирование при помощи команды Compile | Make (ей эквивалентно нажатие клавиши F9) обновит все подключаемые к программе модули, которые либо еще не были откомпилированы, либо изменились с момента последней компиляции. Кроме того, перекомпилированы будут также модули, которые обращаются к тем модулям, чьи секции связи изменились (изменения в секциях реализации такого эффекта не вызовут).
-
Компиляция, активизированная при помощи команды Compile | Build, затронет все модули, вне зависимости от наличия в них изменений.