Понятие модульного программирования возникло при создании программ большого объема, их увеличивающейся внутренней сложности и коллективном характере разработок. Сейчас понятие модуля включает независимо компилируемые и тестируемые программные единицы со строго определенными интерфейсами, которые могут определяться в различных сочетаниях.
Паскаль является алголоподобным языком, а в таких языках отсутствует модульность. В стандартном Паскале даже нет возможности отдельно транслировать и тестировать подпрограммы. В Турбо Паскале с введением понятия «модуль» стал возможным современный стиль реализации программных пакетов, легко подключаемых к любой программе, а так же ослабли ограничения на суммарный объем готовых программ.
В отличие от подпрограммы модуль считается отдельной программой, то есть представляет собой отдельно хранимую и независимо компилируемую программную единицу.
Модуль – это совокупность или коллекция программных ресурсов, предназначенных для использования другими программами или модулями. Ресурсы – это любые программные объекты Паскаля, – константы, переменные, типы, подпрограммы.
Основное отличие модуля от программы заключается в том, что его объекты только используются другими программами, но сам модуль выполнить нельзя.
Все программные ресурсы модуля делятся на две части:
1). Интерфейс. Здесь находятся видимые объекты, то есть те, которые можно использовать в других программах, и предназначенные именно для этих целей.
2). Реализация. Сюда помещают рабочие объекты, называемые невидимыми или скрытыми. Например, если модуль содержит подпрограмму универсального применения, то вызываемые этой подпрограммой процедуры и функции, содержащиеся в модуле, и используемые ею переменные могут иметь чисто внутренний характер и не должны использоваться другими программами.
В разделе реализации так же может находиться секция инициализации, содержащая любые операторы. Они будут выполняться сразу после запуска программы до операторов основной программы. Используется обычно для установки различных начальных значений. Если в Турбо Паскале секция инициализации начиналась со слова Begin, то в Delphi 1.0 для этих целей введено новое служебное слово Initialization.
Начиная с Delphi 2.0, здесь может использоваться и секция завершения (finalization), в которой выполняются действия, противоположные секции инициализации. Например, закрытие файлов, восстановление векторов прерываний и другие.
Таким образом, общая структура модуля следующая:
UNIT <имя модуля>
Interface
<описание видимых объектов>
Implementation
<описание скрытых объектов>
[ Begin {Initialization}
<операторы инициализации>
{ Finalization
<завершающие операторы> } ]
end.
Например, модуль, подключаемый при работе с комплексными числами:
Unit COMPLEX;
Interface
Type Complex = Record
Re,Im:Real;
end;
Function CADD (A,B:complex):complex;
Function CMUL (A,B:complex):complex;
Function CDIV (A,B:complex):complex;
... ...
Implementation
Function CADD;
... {тело функции}
Function CDIV;
Var X:Real; {скрытая переменная}
... ...
end.
При использовании процедур и функций есть некоторые особенности. Заголовок подпрограммы содержит всю информацию, необходимую для ее вызова: имя, количество и тип параметров, и для функций тип результата. Тело же подпрограммы содержит блок, раскрывающий его алгоритм. Можно считать, что заголовок подпрограммы является ее интерфейсом, а тело – реализацией. Поэтому в интерфейсной части модуля должны быть представлены только заголовки процедур и функций, доступные для других программ, по аналогии с опережающим описанием. Полные же описания с сокращенным заголовком помещают в раздел реализации.
Таким образом, программа может связываться с модулем через описания видимых объектов, то есть через интерфейс модуля. Поэтому, если необходимо расширить модуль или изменить реализацию какой-либо подпрограммы, и если интерфейс модуля при этом не меняется, то такое изменение никак не отразится на использующих программах.
§9.2. Использование модулей
Модуль компилируется так же, как и обычные программы, но так как модуль сам по себе не выполняем, то в результате получается специальный файл с расширением TPU (Turbo Pascal Unit).
Для того чтобы получить доступ к интерфейсным объектам модуля, необходимо указать в программе имя нужного TPU-файла в разделе спецификаций используемых модулей, идущего сразу за заголовком:
USES <список модулей>;
При ее наличии в программе считаются известными все описания из интерфейсной части подключенного модуля, и к ним можно обращаться так же, как если бы они были описаны в самой этой программе:
Program Prim;
Uses Complex;
Var R,X,Y,Z: Complex;
Begin
Read (X.RE,X.IM,Y.RE,Y.IM,Z.RE,Z.IM);
R := CADD(CMUL(X,Y),CADD(CMUL(X,Z),CMUL(Y,Z)));
Writeln(R.RE,'+',R.IM,'i')
end.
Правила использования.
1. Иногда некоторые имена используемого модуля могут совпадать с именами использующей его программы. Тогда интерфейсные имена модуля, указанного в списке первым, образуют самый внешний блок программы, имена второго модуля образуют блок, вложенный в первый и т.д.
Например, в программе есть спецификация:
Uses A,B;
то вложенность блоков будет следующей:
То есть имена выполняемой программы «экранируют» одинаковые имена модулей А и В. Получить доступ к одноименным переменным модуля можно, используя составное имя.
Пусть есть модуль:
Unit A;
Interface
Var X:Real;
Procedure Pr(Y:integer);
implementation
... ...
end.
Пусть программа, использующая этот модуль, так же содержит переменную Х:
Program P;
Uses A;
Var X:Integer;
Begin
... ...
X:=8; { определение внутренней целой переменной }
A.X:=2.5; { переменная модуля (составное имя) }
Pr(X); { X - фактический целый параметр-значение }
... ...
end.
2. Разрешены косвенные использования модулей. Причем в спецификации использования указываются только модули, непосредственно используемые в программе. Пример косвенного использования модуля А в программе Р:
Unit A; Unit B; Program P;
Interfase Interfase Uses B;
... ... Uses A; ... ..
end. ... ... end.
end.
3. Схема взаимного использования модулей может иметь структуру любой сложности, но недопустимо явное или косвенное обращение модуля к самому себе.
Unit A; Unit B;
Interfase Interfase
Uses B; Uses A; <- недопустимо
... ... ... ...
4. При наличии раздела инициализации операторы модуля выполняются первыми в порядке описания:
Program P;
Uses A,B;
... ...
Выполняются:
-
операторы модуля А;
-
операторы модуля В;
-
операторы программы Р.
5. Рекомендуется, чтобы имя модуля совпадало с именем файла на внешнем носителе информации, например:
Unit Module1;
... ...
Текст программы необходимо поместить в файл Module1.pas, а оттранслированный модуль будет находиться в файле Module1.tpu. При необходимости хранить код модуля в файле с другим именем используют директиву компилятора $U. Она имеет параметр дискового имени файла с данным модулем и должна находится непосредственно перед именем модуля в спецификации пользователя. Например, запись
Uses {$U MY} MyUnit;
приведет к тому, что компилятор будет искать код модуля MyUnit в файле MY.TPU.
Достарыңызбен бөлісу: |