Правила создания пользовательских модулей в паскале. Подключаемые модули - Pascal. Написание собственных модулей
Модуль (unit) представляет собой набор констант, типов данных, переменных, процедур и функций. Каждый модуль аналогичен отдельной программе на Паскале: он может иметь основное тело, которое вызывается перед запуском Вашей программы и осуществляет необходимую инициализацию. Короче говоря, модуль представляет собой библиотеку описаний, которую можно вставить в свою программу и которая позволит разбить программу на части, компилируемые отдельно.
Турбо-Паскаль обеспечивает Вам доступ к большому числу встроенных констант, типов данных, переменных, процедур и функций. Некоторые из них специфичны для Турбо-Паскаля; другие специфичны для персонального компьютера РС фирмы IBM (и совместимых с ним компьютеров) или для операционной системы MS-DOS. Их количество велико, однако, в своей программе Вы редко используете их все сразу. Поэтому они разделены на связанные группы, называемые модулями. В этом случае Вы можете использовать только те модули, которые необходимы в программе.
Структура модуля
Модуль обеспечивает набор средств благодаря процедурам и функциям при поддержке констант, типов данных и переменных, однако действительная реализация этих средств скрыта в силу того, что модуль разделен на две секции: интерфейса и реализации. Если программа использует модуль, то все описания модуля становятся доступными этой программе, как если бы они были определены в ней самой.
Структура модуля аналогична структуре программы, однако есть несколько существенных различий. Например, рассмотрим модуль:
unit <идентификатор>; interface uses <список модулей>; {Необязательный} {открытые описания} implementation {закрытые описания процедуры и функции } begin {код инициализации } end .Заголовок модуля начинается зарезервированным словом unit, за которым следует имя модуля (идентификатор) точно так же, как и в случае имени программы. Следующим элементом в модуле является ключевое слово interface. Оно обозначает начало секции интерфейса модуля - секции, видимой всем другим модулям или программам, в которых он используется.
Модуль может использовать другие модули, для этого они определяются в предложении uses. Предложение uses, если имеет место, то следует сразу после ключевого слова interface. Отметим, что здесь выполняется общее правило использования предложения uses: если модуль, имя которого указано в предложении uses, использует другие модули, то имена этих модулей также должны быть указаны в предложении uses, причем до того, как они будут использованы.
Стандартные модули
Файл TURBO.TPL содержит все стандартные пакеты, кроме Graph и пакетов совместимости (Graph3 и Turbo3): System, Overlay, Crt, Dos и Printer. Эти пакеты загружаются в память вместе с Турбо-Паскалем и всегда вам доступны. Обычно файл TURBO.TPL хранят в одном каталоге с TURBO.EXE (или TPC.EXE). Вы можете хранить его и в другом каталоге, если он описан как каталог Турбо-Паскаля. Для этого необходимо с помощью TINST.EXE установить этот каталог в файле TURBO.EXE.
Используемые пакеты: нет
System содержит все стандартные и встроенные процедуры и функции Турбо-Паскаля. Любая подпрограмма Турбо-Паскаля, не являющаяся частью стандартного Паскаля и не находящаяся ни в каком другом модуле, содержится в System. Этот модуль присоединяется ко всем программам.
Используемые пакеты: нет
DOS определяет многочисленные паскалевские процедуры и функции, которые эквивалентны наиболее часто используемым вызовам DOS, как например, GetТime, SetТime, DiskSize и так далее. Кроме того, он определяет две программы низкого уровня МsDos и Intr, которые позволяют активизировать любой вызов MS-DOS или системное прерывание. Registers представляет собой тип данных для параметра в МsDos и Intr. Кроме того, определяются некоторые другие константы и типы данных.
Используемые пакеты: нет
Overlay - содержит инструменты для создания оверлейных программ. Программа OVERKAY - программа, которая загружается не вся, а по частям.
Используемые пакеты: нет
Crt обеспечивает набор специфичных для РС описаний констант, переменных и программ для операций ввода/вывода. Последние можно использовать для работы с экраном (задание окон, непосредственное управление курсором, цвет текста и фона). Кроме того, Вы можете осуществлять "необработанный" ввод с клавиатуры и управлять платой генерации звукового сигнала персонального компьютера. Этот модуль обеспечивает множество подпрограмм, которые были стандартными в версии 3.0.
Используемые пакеты: Crt
В модуле Printer дано описание переменной текстового файла Lst, которая связывается с драйвером устройства, позволяющим направлять стандартный для Паскаля вывод на печатающее устройство с помощью Write и Writeln. Например, включив Printer в свою программу, Вы можете сделать следующее:
Write (Lst,"Сумма " ,A:4 ," и " ,B:4 ," равна " ) ; C:=A + B; Writeln (Lst,C:8 ) ;Используемые пакеты: Crt
Graph3 поддерживает полный набор графических подпрограмм для версии 3.0 - для обычной, расширенной графики и графики, использующей относительные команды. Они идентичны по имени, параметрами функции подпрограммам версии 3.0.
Используемые пакеты: Crt
Этот модуль содержит две переменные и несколько процедур, которые больше не поддерживаются Турбо-Паскалем. Они включают встроенную файловую переменную Кbd, булеву переменную CBreak и первоначальные целочисленные версии MemAvail и MaxAvail (которые возвращают размер свободной памяти в параграфах, а не в байтах, как это делают настоящие версии).
Используемые пакеты: Crt
Graph обеспечивает набор быстродействующих, эффективных графических подпрограмм, которые позволяют использовать в полной мере графические возможности Вашего персонального компьютера.
Этот модуль реализует независимый от устройства графический драйвер фирмы "Борланд", позволяющий поддерживать графические адаптеры типа СGА, ЕGА, Hercules, АТТ 400, МСGА, 3270 РС и VGА.
Написание собственных модулей
Допустим, Вы написали модуль IntLib, записали его в файл INTLIВ.PAS и оттранслировали на диск; получившийся в результате код находится в файле INTLIВ.ТРU. Для использования этого модуля в программе необходимо включить в нее оператор uses, указывающий компилятору, какой модуль используется. Ваша программа может выглядеть следующим образом:
program MyProg; uses IntLib;Отметим, что Турбо-Паскаль предполагает, что файл, в котором находится модуль, имеет такое же имя, что и сам модуль. Если имя Вашего модуля МyUtilities, то Турбо-Паскаль будет искать файл с именем МYUTILIТ.PAS.
Компиляция модуля
Модуль компилируется точно так же, как компилируется программа: он создается с помощью редактора, а затем вызывается команда Соmpile/Соmpile (Компилировать/ Компилировать) (или нажимаются клавиши Аlt-С). Однако, вместо файла с расширением.ЕХЕ Турбо-Паскаль создает файл с расширением.ТРU (Turbо Раscal Unit - модуль Турбо-Паскаля). После этого Вы можете оставить этот файл как есть или же вставить его в ТURВО.TPL с помощью TPUMOVER.ЕХЕ.
В любом случае имеет смысл переслать файлы с расширением *.ТРU (вместе с исходными файлами) в каталог модулей, который определен с помощью команды О/D/Unit directories (Каталоги модулей). В одном исходном файле может находиться только один модуль, поскольку компиляция прекращается, как только обнаружен завершающий оператор end.
Пример :
Напишем небольшой модуль. Назовем его IntLib и вставим в него две простые подпрограммы для целых чисел - процедуру и функцию:
unit IntLib; interface procedure ISwap(var I,J: integer ) ; function IMax(I,J: integer ) : integer ; implementation procedure ISwap; var Temp: integer ; begin Temp:=I; I:=J; J:=Temp end ; {конец процедуры ISwap } function IMax; begin if I > J then IMax:=I else IMax:=J end ; {конец функции IMax } end . {конец модуля IntLib }Введем эту подпрограмму, запишем ее в файл INTLIВ.PAS, а затем оттранслируем на диск. В результате получим код модуля в файле INTLIВ.ТРU. Перешлем его в каталог модулей. Следующая программа использует модуль IntLib:
program IntTest; uses IntLib; var A,B: integer ; begin Write ("Введите два целочисленных значения: " ) ; Readln (A,B) ; ISwap(A,B) ; Writeln ("A=" ,A," B=" ,B) ; Writeln ("Максимальное значение равно " ,IMax(A,B) ) ; end . {конец программы IntTest }Все описания внутри модуля связаны друг с другом. Например, модуль Crt содержит все описания, необходимые для подпрограмм работы с экраном на Вашем персональном компьютере.
Модули в Паскале по отношению к основной части программы напоминают подпрограммы (процедуры и функции). Но по определению они являются самостоятельными программами, ресурсы которых могут быть задействованы в других программах. Кроме того описание модулей происходит вне вызывающего приложения, а в отдельном файле, поэтому модуль – это отдельно компилируемая программа. Файл скомпилированного модуля (именно такой нужен для использования) будет иметь расширение предусмотренное средой программирования (например, .tpu , .ppu , .pcu).
Модули создаются, как правило, для обеспечения компактности кода, о чем приходиться заботиться крупным проектам. Стоит также отметить, что использование модулей в каком-то смысле снимает ограничение на сегментацию памяти, так как код каждого модуля располагается в отдельном сегменте.
Структура модуля выглядит так:
Unit <имя модуля>; Interface <интерфейсная часть> Implementation <исполняемая часть> Begin <инициализация> End.
Имя модуля (Unit)
Имя модуля, следующее после ключевого слова Unit , должно совпадать с названием файла (без.pas), в котором находиться его код. Также с помощью имени, модуль подключается к другому модулю, либо к основной программе. Для этого необходимо указать служебное слово Uses, и перечислить через запятую список подключаемых модулей:
Uses <список имен модулей>;
Интерфейсная часть (Interface)
В интерфейсной части описываются заголовки объектов, к которым будут иметь доступ другие модули и программы. Это константы, типы, переменные и подпрограммы. Например, так может выглядеть интерфейсная часть модуля Search , содержащего в себе алгоритмы поиска элементов в массиве.
Unit Search; Interface type arr = array of integer; var s: string; procedure binary_search(x: integer; Ar: arr; var s: string); procedure line_search(x: integer; Ar: arr; var s: string);
Для объявления данного модуля, в программе нужно указать его имя:
После чего станет возможным использование всех описанных в интерфейсной части объектов.
Исполняемая часть (Implementation)
Начинается этот раздел со слова Implementation (реализация). Именно здесь нужно описать подпрограммы, объявленные в интерфейсной части. При этом в их заголовках разрешается не указывать формальные параметры, иначе они должны полностью совпадать с таковыми в интерфейсной части. Кроме этого, интерфейсная часть может содержать локальные (недоступные вызывающей программе) для модуля объекты.
Инициирующая часть
Инициирующая часть начинает свою работу до начала выполнения основной программы. В ней (между Begin и End), как правило, описываются операторы, предназначенные для разного рода вспомогательной работы. Данная часть может отсутствовать, либо не иметь в себе никакого кода. В первом случае нужно указать End с точкой, во втором – оставить пустое место внутри Begin и End .
Компиляция модулей
Использовать в программе можно лишь скомпилированные модули, имеющие расширение, предусмотренное вашей средой разработки приложений. Рассмотрим три наиболее популярные из них:
компиляция модулей в Turbo Pascal
Итогом компиляции модуля в Turbo Pascal , будет файл с расширением .tpu (Turbo Pascal Unit ), хранящий его код.
компиляция модулей в Free Pascal
После компиляции модуля в среде Free Pascal , создаются два файла с разными разрешениями: .ppu и .o . Первый содержит интерфейсную часть модуля, а второй (необходим для компоновки программы) – часть реализаций.
компиляция модулей в Pascal ABC.NET
Pascal ABC.Net во время компиляции модуля не генерирует код на машинном языке. В случае, если компиляция выполнена успешна код сохраняется в файле с разрешением.pcu.
Для сред программирования Turbo Pascal и Free Pascal предусмотрены три режима компиляции: Compile, Make и Build. В режиме Compile все используемые в программе модули должны быть заранее скомпилированы. Приложение в режим Make-компиляции проверяет все подключенные модули на наличие файлов с соответствующим для среды программирования разрешением (.tpu или.o). Если какой-то из них не найден, то происходит поиск файла с названием ненайденного модуля и расширением.pas. Самый надежный из режимов – Build. Поиск и компиляция файлов (с расширением.pas) в данном режиме происходит даже тогда, когда модульные файлы уже имеются.
Пример: создадим небольшой модуль, содержащий в себе процедуры двоичного и линейного поиска элементов в массиве. Код модуля:
Unit Search;
Interface
type arr = array of integer;
var s: string;
procedure binary_search(x: integer; Ar: arr; var s: string);
procedure line_search(x: integer; Ar: arr; var s: string);
Implementation
var a, b, c, i: integer;
procedure binary_search(x: integer; Ar: arr; var s: string);
begin
a:=1; b:=5; s:="NO";
while a<=b do
begin
c:=a+(b-a) div 2;
if (x
Весь этот код должен находиться в отдельном файле. Теперь напишем основную программу, в которую подключим наш модуль Search .
Program modul_search; uses Crt, Search; var mas: array of integer; n, j: integer; str: string; y: char; begin clrscr; writeln("Enter the array elements"); for j:=1 to 5 do readln(mas[j]); write("Enter number search: "); readln(n); write("This array is ordered? (y/n) "); readln(y); if y="y" then binary_search(n, mas, str) else line_search(n, mas, str); write(str); readkey; end.
После компиляции файлов данное приложение должно исправно работать. Конечно, если вы, отвечая на вопрос “Этот массив упорядочен?” укажите программе ложную информацию, то и она может ответить тем же.
Модуль
(UNIT
-модуль, единица) – автономно (отдельно) компилируемая программная единица, которая содержит компоненты раздела описаний (меток, констант, типов, переменных, процедур, функций), а также может содержать операторы инициализирующей части.
Сам модуль не является выполняемой программой, а предназначен для использования другими программами и модулями.
Структура модуля
Модуль имеет следующую структуру:
UNIT <
имя модуля>
INTERFACE
<
раздел интерфейсный>
IMPLEMENTATION
<
раздел реализации>
BEGIN
<
раздел инициализации>
END.
Заголовок модуля состоит из зарезервированного слова Unit (модуль) и имени модуля.
Имя модуля выбирается по общим правилам и должно совпадать с именем дискового файла содержащего исходный текст модуля.
Расширение в имени модуля (.pas
) не указывается оно задается по умолчанию.
Имя модуля используется для его связи с основной программой с помощью предложения Uses.
Предложение Uses
м.б. помещено после заголовка модуля или за словами
Interface и Implementation.
Интерфейсная часть Interface (интерфейс, сочленение, соединение) и содержит обращение к другим модулям и объявления (описания) глобальных объектов т. е. меток, констант, типов, переменных, и заголовков процедур и функций которые доступны основной программе и другим модулям (т. е. видимые из вне).
Раздел реализации – начинается с ключевого словаImplementation (выполнение) и содержит описание локальных для модуля объектов т. е. меток, констант, типов, переменных которые не доступны основной программе и другим модулям (т. е. не видимые из вне) и полное описание процедур и функций. При этом в заголовке подпрограмм список формальных параметров м.б. опущен, но если он приводится то должен точно соответствовать описанию в интерфейсной части.
Раздел инициализации
– заключается в словесные скобки BEGIN END
.
и содержит операторы, которые будут выполнены до передачи управления основной программе. Это м.б. операторы инициализации данных (переменных) Например операторы присваивания, ввода а также процедуры связывания и открытия файлов. Раздел операторов м.б. пустымBEGIN END
или отсутствовать простоEND.
В конце модуля ставится точка.
Компиляция и использование модулей
Оперативная память система имеет сегментную структуру (один сегмент равен 64К =65535 байт). Код программы м.б. не более одного сегмента, объем данных не может превышать один сегмент (если не использовать динамическую память) и для стека один сегмент. Размер стека задается директивой {$M
<>}. Минимальный размер стека 1К максимальный один сегмент по умолчанию 16К. Значения локальных переменных при обращении к подпрограмме помещаются в стек, а при выходе извлекаются из стека.
Код модуля помещается в отдельный сегмент, т.к. он транслируется автономно от основной программы, а количество модулей используемых программой зависит только от доступной ОП. Это позволяет создавать большие программы.
Компилятор создает код модуля с тем же именем, но с расширением tpu
(turbo pascal unit
).
Для использования модуля основной программой или другими модулями его имя (без расширения) помещается в списке предложенияUses
Если модуль является компактным и часто м.б. использован прикладными программами, то его можно поместить в библиотеку стандартных модулейTURBO.TPL (Turbo-Pasacal-library)
с помощью утилитыTPUMOVER
.
Но это необходимо делать только в случае крайней необходимости т.к. библиотека загружается в ОП и уменьшает место для программы.
При компиляции файла с исходным текстом модуля появляется одноименный файл с расширением tpu
и помещается в каталоге указанном опцией
OPTIONS/DIRECTORIES/UNIT DIRECTORIES
или в текущем каталоге при отсутствии этой опции.
При компиляции основной программы используемые модули д.б. в каталоге указанном опцией
OPTIONS/DIRECTORIES/EXE & TPU DIRECTORIES
либо в текущем каталоге при отсутствии этой опции
Для получения EXE
файла задачи в опции
COMPILE/DESTINATION/DISK(MEMORI)
установить DISK
.
Существует три режима компиляции модулей:
- COMPILE
- BUILD
- MAKE
Режимы устанавливаются меню COMPILE
1. Режим COMPILE
(вызывается Alt-F9
) . При этом компилируется программа а используемые модули д.б. предварительно откомпилированы и храниться в соответствующих каталогах.
2. Режим BUILD
(вызывается -
F9
) . При этом игнорируются ранее откомпилированные модули, а ищутся модули с расширением pas
и перекомпилируются.
3. Режим MAKE
(вызываетсяF9
) . При этом перекомпилируется только модули, которые имели изменения в тексте.
Пример 16.1.
В файле inp.txt расположены три массива вещественных чисел
2.1 3.1 -2.4 5.6 5.4 -6.7 3.5 -3.6
Вычислить функцию
где Max_a, Max_b, Max_c, Sa, Sb, Sc, ka, kb, kc - максимальный элемент, сумма и количество положительных элементов соответствующих массивов a, b, и c.
Результат вывести в файл out.
txt
и на экран.
Текст модуля
Unit UNMAS;
Interface
Const n=10;
Type vec=array of real;
Var z:vec;
i:integer;
f1,f2:text;
Procedure SK1(z:vec; num:byte; Var s:real; Var k:byte);
Function MAX(z:vec; num:byte):real;
Implementation
Procedure Vv(s:char; num:byte;Var z:vec);
Begin
Writeln("Mассив ",s);
For i:=1 to num do
Begin
Read(f1,z[i]); Write(z[i]:4:1," ":3);
End;
Readln(f1); Writeln;
End;
Procedure SK1(z:vec;num:byte; Var s:real; Var k:byte);
Begin
s:=0; k:=0;
for i:=1 to num do if z[i]>0 then
Begin
s:=s+z[i];
k:=k+1
End;
End;
Function MAX(z:vec;num:byte):real;
Var m:real;
Begin
m:=z;
for i:=1 to num do if z[i]>m then m:=z[i];
MAX:=m
End;
Begin
Assign(f1,"inp.txt"); Reset(f1);
Assign(f2,"out.txt"); Rewrite(f2)
End.
Текст программы
Program lr7_16;
Uses CRT,UNMAS;
Var
a,b,c:vec;
y,sa,sb,sc:real;
ka,kb,kc:byte;
Begin
clrscr;
Vv("a",8,a);
Vv("b",9,b);
Vv("c",n,c);
SK1(a,8,sa,ka);
SK1(b,9,sb,kb);
SK1(c,n,sc,kc);
y:=(MAX(a,8)+MAX(b,9)+MAX(c,n))+(sa+sb+sc+ka+kb+kc);
Writeln("Результат:":20);
Write ("Массив а: ");
Writeln("sa=",sa:5:1," ka=",ka);
Write ("Массив b: ");
Writeln("sb=",sb:5:1," kb=",kb);
Write ("Массив c: ");
Writeln("sc=",sc:5:1," kc=",kc);
Writeln(" ":10,"y=",y:10);
Readln;
Writeln(f2,"ђҐ§г«мв в:");
Writeln(f2," ":10,"y=",y:10);
Close(f1);
Close(f2)
End.
Результаты работы программы
Mассив a
-2.1 3.1 -2.4 5.6 5.4 -6.7 3.5 -3.6
Mассив b
2.3 -4.3 2.1 2.5 -3.7 -5.6 4.6 3.5 -7.5
Mассив c
-2.1 4.3 -2.3 7.6 4.5 -8.9 5.7 -4.5 6.8 -5.8
Результат:
Массив а: sa= 17.6 ka=4
Массив b: sb= 15.0 kb=5
Массив c: sc= 28.9 kc=5
y= 9.330E+01
Подключаемые модули.
1. Основные положения
Подключаемый модуль – файл, содержащий исходный текст на языке Pascal, имеющий определенную структуру, предназначенный для использования как в главной программе, так и в других подключаемых модулях. Использование заключается в подключении модуля в разделе uses, путем указания его имени.2. Общая структура подключаемого модуля
Unit <имя модуля>; Interface Implementation End.
Структурно в подключаемом модуле можно выделить три раздела: 1) Интерфейсный раздел – interface (должен быть объявлен, может быть пустым) 2) Раздел реализаций – implementation (должен быть объявлен, может быть пустым) 3) Тело модуля – begin-end. (может отсутствовать)
2.1. Интерфейсный раздел.
Интерфейсный раздел – область подключаемого модуля, начинающаяся с ключевого слова interface и заканчивающаяся ключевым словом implementation, которая может содержать: - список подключаемых модулей; - константы; - пользовательские типы данных; - переменные; - прототипы процедур и функций, доступные из места подключения данного модуля. Замечание 1: переменные, объявленные в разделе интерфейсов, являются глобальными. То есть существуют в любом месте программы, где подключен данный модуль, в том числе в разделе реализации самого модуля. Замечание 2: как и в программе, вышеперечисленные секции (объявления констант, переменных и др., за исключением секции uses) в данном разделе могут быть расположены в любой последовательности и в любом количестве. Замечание 3: если в данном разделе объявляются прототипы процедур/функций, то их реализации должны гарантированно присутствовать в разделе implementation. Основное назначение: определяет общедоступные данные/функционал для применения из программы или модуля, использующих данный модуль.Пример интерфейсного раздела:
Interface {подключаемые модули} Uses AnotherUnit; {константы} Const PI=3.14159265; E=2.71828182; {пользовательские типы данных} Type TMyType=array[-3..7] of real; {переменные} Var temp:TMyType; {процедуры и функции} Procedure Fill(var x:TMyType); Function Find(const x:TMyType; const Value:real):Boolean; Implementation
2.2. Раздел реализаций.
Раздел реализаций – область подключаемого модуля, начинающаяся с ключевого слова implementation и заканчивающаяся телом модуля (если таковое имеется) или ключевым словом end с точкой, означающим конец модуля, в которой располагаются реализации процедур и функций, объявленных в интерфейсном разделе, которая может содержать: - список подключаемых модулей; - константы; - пользовательские типы данных; - переменные; - процедуры и функции, необходимые для реализации процедур/функций, объявленных в интерфейсном разделе. Основное назначение: реализация процедур и функций, описанных в секции interface. Замечание 1: при реализации процедур и функций, описанных в интерфейсной секции, их заголовки могут быть описаны в сокращенной форме. Исключение - PascalABC: при использовании переменных заголовка в тексте реализации возникает ошибка компиляции.Пример 1 (заголовки в сокращенной форме):
Unit DemoUnit; Interface {прототип процедуры} Procedure Swap(var a,b:integer); Implementation {реализация процедуры} Procedure Swap; Var Temp:integer; Begin Temp:=a; a:=b; b:=Temp; end; end.
Пример 2 (заголовки в полной форме):
Unit DemoUnit; interface {прототип функции} Function GetMax(a,b:integer):integer; Implementation {реализация функции} Function GetMax(a,b:integer):integer; Begin If a>b then GetMax:=a Else GetMax:=b; End; End.
2.3. Тело модуля.
Тело модуля – последняя область подключаемого модуля, образуемая парой ключевых слов: «begin» и «end.», в которой можно размещать программный код аналогично главной программе. Тело модуля может отсутствовать. В таком случае ключевое слово «begin» не пишется, а «end.» сигнализирует о конце модуля. Основное назначение: инициализация переменных модуля, выделение ресурсов, необходимых для его работы и т.д.Пример модуля, содержащего тело:
Unit DemoUnit; Interface Const N=50; Var Roots:array of real; Implementation Uses Math; Var I:integer; {тело модуля} Begin For i:=1 to N do Roots[i]:=sqrt(i); End.
Пример модуля без тела: (см. пример модуля для заголовков в полной форме).
Замечание 1: Программный код, размещенный в теле модуля, выполняется один раз – при загрузке модуля, до начала исполнения кода главной программы. Замечание 2: В случае, когда в секции uses подключено несколько модулей, имеющих разделы инициализации, выполнение кода этих разделов идет в порядке подключения модулей.2.4. Дополнительные разделы в структуре модуля.
Компиляторы Free Pascal, Pascal ABC, Pascal ABC.Net допускают помимо перечисленных выше еще два раздела: - раздел инициализации - раздел финализации. 2.4.1. Раздел инициализации. Раздел инициализации – область подключаемого модуля, размещаемая после по окончании раздела реализаций, начинающаяся с ключевого слова initialization и заканчивающаяся разделом финализации, если таковой имеется, или ключевым словом end с точкой. Назначение аналогично телу модуля. 2.4.2. Раздел финализации. Раздел финализации – область подключаемого модуля, размещаемая по окончании раздела инициализации, если таковой имеется, или по окончании раздела реализаций, и заканчивающаяся ключевым словом end с точкой. Основное назначение: освобождение ресурсов, выделенных для работы модуля.
unit DemoUnit; interface var a:array of ^integer;{массив указателей} implementation {выделение памяти и инициализация значениями} procedure AllocateArray; var i:integer; begin for i:=1 to 20 do begin New(a[i]); a[i]^:=i; end; end; {освобождение памяти} procedure DeallocateArray; var i:integer; begin for i:=1 to 20 do Dispose(a[i]); end; initialization AllocateArray;{инициализация - начало работы - выделяем память} finalization DeallocateArray;{финализация - конец работы - осовобождаем память} end.
Замечание 1: программный код, размещаемый в перечисленных разделах, исполняется один раз. Код разделов инициализации – до начала исполнения кода главной программы, код разделов финализации – после. Замечание 2: при наличии в модуле любого из данных двух разделов, наличие тела модуля более не допускается.3. Компиляция модулей.
Каждый подключаемый модуль компилируется отдельно, а результат компиляции зависит от используемого компилятора.
3.1. Компиляция в Turbo Pascal.
Результатом компиляции подключаемого модуля в Turbo Pascal-е является *.tpu – файл (Turbo Pascal Compiled Unit), представляющий собой машинное представление данных и кода, размещенных в нем.
3.2. Компиляция в Free Pascal.
Результатом компиляции подключаемого модуля в Free Pascal-е являются два файла: *.ppu – файл, содержащий интерфейсную часть модуля, и файл *.o - объектный файл, содержащий часть реализаций. Причем последний необходим для компоновки приложения.
3.3. Компиляция в Pascal ABC.Net.
В отличие от перечисленных выше сред в Pascal ABC.Net в процессе компиляции модуля не генерируется код на машинном языке. Компилятор данной среды завершает свою работу после выполнения семантического анализа, сохраняя семантическое дерево модуля в промежуточный формат - *.pcu – файл, который в первом приближении можно считать результатом компиляции с обозначенными ограничениями.
3.4. Ускорение компиляции программ.
На этапе компоновки приложения, компоновщик собирает исполняемый модуль, принимая на вход объектные модули. Таким образом, имея уже откомпилированные подключаемые модули, компиляция программ с их использованием ускоряется, так как они уже обработаны. Данное справедливо для Turbo и Free Pascal-ей. Однако, в Pascal ABC.Net ускорение компиляции достигается только за счет того, что отсутствует необходимость проводить синтаксический и семантический анализ. Вывод: откомпилированные версии исполняемых модулей не совместимы между различными компиляторами.
Код к задаче: «Подключаемые модули»
Textual
Листинг программы
Unit u1; interface procedure PrintFirst; procedure PrintFirstSecond; implementation uses u2; { <--- Раньше было в Interface } procedure PrintFirst; begin writeln("Print first"); end; procedure PrintFirstSecond; begin writeln("Print first"); PrintSecond; end; end.