Оргтехника        23.05.2022   

Пользовательские модули в паскале. Pascal

Модуль (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

Модули в Паскале по отношению к основной части программы напоминают подпрограммы (процедуры и функции). Но по определению они являются самостоятельными программами, ресурсы которых могут быть задействованы в других программах. Кроме того описание модулей происходит вне вызывающего приложения, а в отдельном файле, поэтому модуль – это отдельно компилируемая программа. Файл скомпилированного модуля (именно такой нужен для использования) будет иметь расширение предусмотренное средой программирования (например, .tpu, .ppu, .pcu).

Модули создаются, как правило, для обеспечения компактности кода, о чем приходиться заботиться крупным проектам. Стоит также отметить, что использование модулей в каком-то смысле снимает ограничение на сегментацию памяти, так как код каждого модуля располагается в отдельном сегменте.

Структура модуля выглядит так:

Unit <имя модуля>;
Interface
<интерфейсная часть>
Implementation
<исполняемая часть>
Begin
<инициализация>
End.

Имя модуля (Unit)

Имя модуля, следующее после ключевого слова Unit , должно совпадать с названием файла (без.pas), в котором находиться его код. Также с помощью имени, модуль подключается к другому модулю, либо к основной программе. Для этого необходимо указать служебное слово Uses , и перечислить через запятую список подключаемых модулей:

Uses <список имен модулей>;

Интерфейсная часть (Interface)

В интерфейсной части описываются заголовки объектов, к которым будут иметь доступ другие модули и программы. Это константы, типы, переменные и подпрограммы. Например, так может выглядеть интерфейсная часть модуля Search, содержащего в себе алгоритмы поиска элементов в массиве.

1
2
3
4
5
6

unit Search;
Interface

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) в данном режиме происходит даже тогда, когда модульные файлы уже имеются.

Пример

Создадим небольшой модуль, содержащий в себе процедуры двоичного и линейного поиска элементов в массиве. Код модуля:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

unit Search;
Interface
type arr = array [ 1 ..5 ] 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 b:= c— 1
else if (x>Ar[ c] ) then
a:= c+ 1
else
begin s:= ‘YES’ ; break ; end ;
end ;
end ;
procedure line_search(x: integer ; Ar: arr; var s: string ) ;
begin
s:= ‘NO’ ;
for i:= 1 to 5 do
begin
if (Ar[ i] = x) then
begin
s:= ‘YES’ ; break ;
end ;
end ;
end ;
end .

Весь этот код должен находиться в отдельном файле. Теперь напишем основную программу, в которую подключим наш модуль Search.

Модуль не представляет собой исполняемой программы, а только содержит набор средств для использования в исполняемой программе: типы данных, переменные, процедуры и функции. Исходный текст модуля имеет расширение.pas. Модуль компилируется отдельно от основной программы, откомпилированный модуль имеет расширение.tpu (Turbo Pascal Unit). Готовый откомпилированный модуль может быть использован в основной программе с помощью предложения uses, которое записывается сразуже после имени программы.

В Турбо Паскале имеются стандартные модули:DOS, CRT (Cathode Ray Tube, электронно-лучевая трубка), Printer, Graph, System и другие. Их не надо описывать, а можно сразу включать в программу предложением uses. Модуль System используется во всех программах, поэтому для него сделано исключение, его можно не включать в предложение uses, он будет подключен автоматически. Остальные модули требуют включения в предложение uses, если в программе используются ресурсы модуля, например, процедуры и функции.

Структура модулей

Модуль имеет следующую структуру:
Unit < имя >;
Interface
< интерфейсная часть >
Implementation
< исполняемая часть >
[ Begin < инициирующая часть > ]
End.

Здесь:
Unit - кодовое слово (англ. модуль); начинающее заголовок модуля;
<имя> - имя модуля (правильный идентификатор);
Interface - кодовое слово, начинающее интерфейсную часть модуля;
Implementation - кодовое слово (англ. реализация); начинает исполняемую часть;
Begin - кодовое слово, начинающее инициирующую часть;
(часть модуля Begin < инициирующая часть > необязательна);
End. - признак конца модуля.

Таким образом, модуль состоит из заголовка и трех составных частей, любая из которых может быть пустой.

Интерфейсная часть открывается кодовым словом Interface . В этой части содержатся объявления всех глобальных объектов модуля (типов, констант, переменных и подпрограмм), которые должны стать доступными основной программе и/или другим модулям.

Следует учесть, что все константы и переменные, объявленные в интерфейсной части модуля, равно как и глобальные объекты основной программы, помещаются компилятором Турбо-Паскаля в обилии сегмент данных (максимальная длина сегмента 65521 байт).

Порядок появления различных разделов объявлений и их количество могут быть произвольными.

В интерфейсной части модулей нельзя использовать опережающее описание.

Исполняемая часть

Исполняемая часть начинается кодовым словом Implementation и содержит тела процедур и функций, объявленных в интерфейсной части. В этой части могут также объявляться локальные для модуля объекты: вспомогательные типы, константы, переменные и блоки, а также метки, если они используются в инициирующей части. Ранее объявленные в интерфейсной части глобальные процедуры и функции должны описываться в той же последовательности, в какой появляются их заголовки в интерфейсной части. Описанию глобального блока в исполняемой части должен предшествовать заголовок, в котором разрешается опускать список формальных переменных (и тип результата для функции), так как они уже описаны в интерфейсной части.

Но если заголовок блока приводится в полном виде, т.е. со списком формальных параметров и объявлением результата, он должен совпадать с заголовком, объявленным в интерфейсной части.

Локальные переменные и константы, а также все программные коды, порожденные при компиляции модуля, помещаются в общий сегмент памяти.

Компиляция модулей

В среде Турбо-Паскаля имеются средства, управляющие способами компиляции модулей и облегчающие разработку крупных программных проектов. В частности, определены три режима компиляции: Compile, Make и Build, Режимы отличаются только способом связи компилируемого модуля или компилируемой основной программы с другими модулями, объявленными в предложении Uses.

При компиляции модуля или основной программы в режиме Compile все упоминающиеся в предложении Uses модули должны быть предварительно откомпилированы и результаты их компиляции должны быть помещены в одноименные файлы с расширением.TPU. Например, если в программе (в модуле) имеется предложение Uses Global, то на диске в каталоге, объявленном опцией Unit directories, уже должен находиться файл GLOBAL.TPU. Файл с расширением.TPU (от англ. Turbo-Pascal Unit) создается в результате компиляции модуля.

В режиме MAKE компилятор проверяет наличие TPU-файлов для каждого объявленного модуля. Если какой-либо из файлов не обнаружен, система пытается отыскать одноименный файл с расширением.PAS, т.е. файл с исходным текстом модуля, и, если PAS- файл найден, приступает к его компиляции. Кроме того, в этом случае система следит за возможными изменениями исходного текста любого используемого модуля. Если внесены какие-либо изменения в PAS-файл (исходный текст модуля), то независимо от того, есть ли уже в каталоге соответствующий TPU-файл или нет, система осуществляет его компиляцию перед компиляцией основной программы.

Более того, если изменения внесены в интерфейсную часгь модуля, то будут перекомпилированы также и все другие модули, обращающиеся к нему. Режим Make, таким образом, существенно облегчает процесс разработки крупных программ с множеством модулей: программист избавляется от необходимости следить за соответствием существующих TPU-файлов и их исходного текста, так как система делает это автоматически.

В режиме Build существующие TPU-файлы игнорируются, и система пытается отыскать (и компилировать) соответствующий PAS-файл для каждого объявленного в Uses модуля. После компиляции в режиме Build программист может быть уверен в том, что учтены все сделанные им изменения в любом из модулей.

Подключение модулей к основной программе и их возможная компиляция осуществляется в порядке их объявления в предложении Uses. При переходе к очередному модулю система предварительно отыскивает все модули, на которые он ссылается. Ссылки модулей друг на друга могут образовывать древовидную структуру любой сложности, однако запрещается явное или косвенное обращение модуля к самому себе.

6 вопрос

Модуль CRT представляет собой библиотеку процедур и описаний, которая расширяет возможности пользователя при работе с текстом, текстовым экраном и клавиатурой. Рассмотрим некоторые из них.

1). TextMode(режим: integer) - выбирает указанный текстовый режим Режимы CRT:

2).TextBackground (цвет: byte) - Выбирает фоновый цвет.

Параметр "цвет" представляет собой выражение целого типа, например:

  • 0- черный
  • 1-синий
  • 2-зеленый
  • 3-голубой

3). ClrScr - Очистка экрана. Все позиции символов заполняются пробелами. При этом используются текущий фоновый цвет, заданный в процедуре TextBackGround.

4). TextColor (цвет:byte) - Устанавливает цвет символов. { константы для установки цвета}

5). Window(x1,y1,x2,y2) - Определяет на экране текстовое окно. Параметры x1,y1 представляют собой координаты верхнего левого угла окна, параметры x2,y2 - координаты правого нижнего угла.Минимальный размер один столбец на одну строку. Максимальный - Х=80, У=25.Если координаты являются недопустимыми, то обращение к процедуре Window игнорируется. По умолчанию задается окно на весь экран.

6).GoToXY(x,y: byte) - Позиционирует курсор. Курсор перемещается в ту позицию внутри текущего окна, которая задана координатами x и y (x - задает столбец, y - задает строку).Верхний левый угол задается координатами (1,1) пример: Window(1,10,60,20); GoToXY(1,1); Это приведет к тому, что курсор уйдет в точку с абсолютными координатами (1,10).

7).WhereX и WhereY возвращают для текущей позиции курсора относительно текущего окна координаты X и Y соответственно. Тип результата Byte.

8).Delay(мсек: word) - Выполняет задержку на заданное число миллисекунд. Параметр "мсек" задает число миллисекунд интервала ожидания. Но данная процедура является приблизительной, поэтому период задержки не будет точно равнятся заданному числу миллисекунд.

9).READKey - Считывает символ с клавиатуры.

10).Sound - является процедурой включающей внутренний динамик; Описание: Sound(герц: word); где параметр "герц" задает частоту генерируемого сигнала в герцах.Звук будет звучать до тех пор пока не будет выключен посредством обращения к процедуре NoSound;

11).NoSound - Выключает внутренний динамик.

Пример использования Sound,Delay,NoSound

Sound(220); { включить звук }

Delay(300); { ждать 300 ms }

NoSound; { выключить звук }

7 вопрос.

Модуль Graph

ТР обладает достаточно разнообразными средствами для работы со стандартным VGA экраном.

VGA адаптер имеет разрешение 640х480 пиксел (точка (0,0) в левом верхнем углу экрана), 16 цветов.

Перед началом работы с графикой необходимо ее инициализировать, а по окончании - "закрыть". Все графические процедуры и функции находятся в модуле Graph, поэтому также необходимо его подключение.

Общая структура графической программы:

Uses crt, graph;
var Gd, Gm: Integer;
begin
Gd:= Detect;
InitGraph(Gd, Gm, "c:\bp\bgi");
...
{Здесь построение изображения}
...
ReadKey;
CloseGraph;
end.

Путь c:\bp\bgi указывает расположение файла egavga.bgi (драйвер графического адаптера). На разный компьютерах этот путь может быть разным. Если файл egavga.bgi поместить в каталог с программой, то путь можно не указывать.

Основные графические процедуры и функции:

Построение фигур

PutPixel(x,y,c)
- отображает на экране точку с координатами (x,y) и цветом c

Line(x1,y1,x2,y2)
- рисует линию с началом в точке (x1,y1) и концом - (x2,y2)

Rectangle(x1,y1,x2,y2)
- рисует контур прямоугольника с диагональю (x1,y1) - (x2,y2)

Bar(x1,y1,x2,y2)
- рисует закрашенный прямоугольник с диагональю (x1,y1) - (x2,y2)

Circle(x,y,r)
- рисует окружность с центром (x,y) и радиусом r

Ellipse(x,y,ba,ea,xr,yr)
- рисует дугу эллипса с центром в (x,y), горизонтальным и вертикальным радиусом xr и yr, и начальным и конечным углом ba и ea

FillEllipse(x,y,xr,yr)
- рисует закрашенный эллипс с центром в (x,y), горизонтальным и вертикальным радиусом xr и yr

Abs в Паскале возвращает абсолютное значение переменной. Результат, возвращаемый функцией Abs, имеет тот же , что и аргумент - параметр, передаваемый в функцию. Этот параметр может иметь любой числовой тип данных.

Синтаксис функции Abs для целых чисел:

function Abs(L: LongInt) : LongInt;

function Abs(I: Int64) : Int64;

Последний вариант возможен только для и , так как в классическом Паскале нет типа данных Int64.

Синтаксис функции Abs для вещественных чисел:

function Abs(D: ValReal) : ValReal;

ValReal - это вещественный тип данных с наибольшим доступным значением в данной операционной системе. Фактически это псевдоним (алиас) одного из типов Extended или Double.

А теперь пример использования:

Program absfunc; var x: integer = -100; y: integer; begin y:= Abs(x); //у = 100 WriteLn("Abs(-100) = ", y); //Выведет 100 ReadLn; end.

Здесь мы сначала объявляем переменную с начальным значением равным -100 (отрицательное число).

А в программе используем функцию Abs и в результате переменная у будет равна 100 (положительное число).

Что вычисляет функция Abs

Вообще Abs - это сокращение от Absolute. Как нетрудно догадаться, переводится это слово как “абсолютный, чистый, несомненный”.

Вы должны помнить из школьного курса математики, что абсолютное число, то есть абсолютная величина или модуль числа х - это неотрицательное число, определение которого зависит от типа числа х.

В математике модуль числа х обозначается так: |x|.

То есть функция Abs в любом случае возвращает положительное число. Такая функция есть практически во всех языках программирования, так как используется довольно часто и входит в основы математики.

Таким образом, можно сказать, что функция Abs(х) вычисляет модуль числа х. То есть Abs(х) в Паскале - это то же самое, что |x| в математике.

Ну и напоследок давайте создадим свой собственный аналог функции, которая возвращает модуль числа. Итак, функция будет примерно такая:

Function MyAbs(iNum: integer) : integer; begin if iNum

Здесь мы передаём в функцию целое число, которое может быть как отрицательным, так и положительным. В функции мы проверяем значение этого числа. Если число отрицательное, то мы умножаем его на -1, и таким образом получаем положительное число. Если число положительное, то мы ничего не делаем - просто возвращаем полученное через параметр iNum число.

Как видите, алгоритм довольно простой.

Правда, наша функция может работать только с целыми числами. Но это уже мелочи...

Подключаемые модули.

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.