Основы программирования — Осенний семестр; Михалкович С.С.; 2008; V — различия между версиями
Juliet (обсуждение | вклад) (Новая: Категория:Конспекты Категория:Основы программирования ==Модули== === Введение === '''Модуль''' — это с...) |
Admin (обсуждение | вклад) (→Модули) |
||
(не показано 12 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
− | |||
[[Категория:Основы программирования]] | [[Категория:Основы программирования]] | ||
− | ==Модули== | + | [[Страница курса Основы программирования|К основной странице курса]] |
+ | == Модули == | ||
=== Введение === | === Введение === | ||
'''Модуль''' — это совокупность взаимосвязанных процедур, функций, типов, переменных и констант, | '''Модуль''' — это совокупность взаимосвязанных процедур, функций, типов, переменных и констант, | ||
предназначенных для решения ряда однотипных задач, и помещенных в специальным образом оформленный файл. | предназначенных для решения ряда однотипных задач, и помещенных в специальным образом оформленный файл. | ||
− | Модули разбивают большой проект на относительно независимые части, при этом, каждая часть "живет своей жизнью": модуль, написанный для одного программного проекта может быть использован в другом программном проекте. | + | Модули разбивают большой проект на относительно независимые части, при этом, каждая часть "живет своей жизнью": модуль, написанный для одного программного проекта, может быть использован в другом программном проекте. |
− | Различают модули в виде '''''исходных текстов''''' и '''''откомпилированные модули'''''. | + | Различают модули в виде '''''исходных текстов''''' и '''''откомпилированные модули'''''. <br /> |
− | <br>Откомпилированные модули уменьшают суммарное время компиляции и позволяют ''скрывать программный код от модификации''. | + | Откомпилированные модули уменьшают суммарное время компиляции и позволяют ''скрывать программный код от модификации''. |
− | '' | + | ''<u>Пример</u>.'' <br /> |
− | + | <u>Модуль <tt>MyLib</tt></u> | |
− | <source lang="Pascal">unit MyLib; | + | <source lang="Pascal"> |
+ | unit MyLib; | ||
interface // раздел интерфейса | interface // раздел интерфейса | ||
Строка 29: | Строка 30: | ||
function MySqr(a: real): real; | function MySqr(a: real): real; | ||
begin | begin | ||
− | + | Result := a * a; | |
end; | end; | ||
function AddSquares(a, b: real): real; | function AddSquares(a, b: real): real; | ||
begin | begin | ||
− | + | Result := MySqr(a) + MySqr(b); | |
end; | end; | ||
Строка 42: | Строка 43: | ||
end; | end; | ||
− | end. // конец модуля</source> | + | end. // конец модуля |
+ | </source> | ||
− | + | <u>Программа, подключающая модуль <tt>MyLib</tt></u> | |
− | <source lang="Pascal">uses MyLib; | + | <source lang="Pascal"> |
+ | uses MyLib; | ||
var | var | ||
Строка 54: | Строка 57: | ||
writeln(AddSquares(3, 4)); | writeln(AddSquares(3, 4)); | ||
InvertPrint(3,4); | InvertPrint(3,4); | ||
− | end.</source> | + | end. |
− | + | </source> | |
− | Модуль в языке Object Pascal состоит из двух разделов: | + | Модуль в языке ''Object Pascal'' состоит из двух разделов: |
− | *раздел '''интерфейса''' | + | * раздел '''интерфейса''' |
− | *раздел '''реализации''' | + | * раздел '''реализации''' |
− | В разделе | + | В разделе ''интерфейса'' описываются все |
− | + | * ''переменные'' | |
− | + | * ''константы'' | |
+ | * ''типы'' | ||
+ | * ''заголовки подпрограмм'', | ||
+ | которые можно будет использовать в других модулях, подключающих данный. | ||
− | В разделе | + | В разделе ''реализации'' содержится |
− | + | * ''реализация подпрограмм'', заголовки которых приведены в разделе интерфейса | |
− | + | * описание ''вспомогательных'' констант, переменных, типов и подпрограмм, | |
− | + | которые нужны для реализации подпрограмм из раздела интерфейса и не видны из других модулей. | |
− | |||
− | Данный принцип получил название '''принципа сокрытия информации'''. | + | Данный принцип получил название '''принципа сокрытия информации'''. <br /> |
− | <br>Его ''преимущества'': | + | Его '''преимущества''': |
− | *уменьшение количества информации, необходимой для понимания работы модуля | + | * уменьшение количества информации, необходимой для понимания работы модуля |
− | *сокрытие реализации от клиентов | + | * сокрытие реализации от клиентов |
− | *возможность легкого изменения реализации в следующих версиях без изменения интерфейса, т.е. без затрагивания интерфейса клиентов | + | * возможность легкого изменения реализации в следующих версиях без изменения интерфейса, т.е. без затрагивания интерфейса клиентов |
− | *возможность скрыть программный код от клиентов, предоставив им лишь откомпилированную версию модуля | + | * возможность скрыть программный код от клиентов, предоставив им лишь откомпилированную версию модуля |
− | |||
=== Синтаксис модуля === | === Синтаксис модуля === | ||
'''unit''' <имя модуля>; | '''unit''' <имя модуля>; | ||
Строка 98: | Строка 102: | ||
=== Семантические ограничения === | === Семантические ограничения === | ||
− | *Модули, перечисленные в секции <tt>'''uses'''</tt> в разделах интерфейса и реализации не должны пересекаться | + | * Модули, перечисленные в секции <tt>'''uses'''</tt> в разделах интерфейса и реализации не должны пересекаться |
− | *''циклическая зависимость'' между модулями в разделе интерфейса '''запрещена''': | + | * ''циклическая зависимость'' между модулями в разделе интерфейса '''запрещена''': |
'''unit''' A; '''unit''' B; | '''unit''' A; '''unit''' B; | ||
'''interface''' '''interface''' | '''interface''' '''interface''' | ||
Строка 109: | Строка 113: | ||
'''uses''' A; | '''uses''' A; | ||
:потому что модули '''''компилируются в два этапа''''': | :потому что модули '''''компилируются в два этапа''''': | ||
− | :*интерфейс | + | :* интерфейс |
− | :*реализация | + | :* реализация |
=== Разделы инициализации и финализации модуля === | === Разделы инициализации и финализации модуля === | ||
Строка 121: | Строка 125: | ||
'''end'''. '''end'''. | '''end'''. '''end'''. | ||
− | Операторы в разделе '''<tt>initialization</tt>''' модуля выполняются ''раньше'' тела основной программы, | + | Операторы в разделе '''<tt>initialization</tt>''' модуля выполняются ''раньше'' тела основной программы, <br /> |
− | <br /> а операторы в разделе <tt>'''finalization'''</tt> выполняются''после'' основной программы. | + | а операторы в разделе <tt>'''finalization'''</tt> выполняются ''после'' основной программы. |
Т.е. последовательность выполнения будет такой: | Т.е. последовательность выполнения будет такой: | ||
Строка 128: | Строка 132: | ||
<операторы<sub>3</sub>> | <операторы<sub>3</sub>> | ||
<операторы<sub>2</sub>> | <операторы<sub>2</sub>> | ||
+ | |||
'''Примечание.''' В разделе ''инициализации'' обычно инициализируются глобальные переменные из раздела интерфейса. | '''Примечание.''' В разделе ''инициализации'' обычно инициализируются глобальные переменные из раздела интерфейса. | ||
− | <u>Пример</u>. | + | ''<u>Пример</u>.'' |
− | <source lang="Pascal">unit A; | + | <source lang="Pascal"> |
+ | unit A; | ||
interface | interface | ||
Строка 145: | Строка 151: | ||
=== Схема компиляции программы с модулями === | === Схема компиляции программы с модулями === | ||
− | + | [[Изображение:Схема компиляции модуля.png|500px|thumb|right|Схема компиляции программы с модулями]] | |
− | |||
1. Компилируется файл основной программы. | 1. Компилируется файл основной программы. | ||
<br />2. Если в нем встречена секция <tt>'''uses'''</tt>, то компилируются модули из этой секции ''слева направо''. | <br />2. Если в нем встречена секция <tt>'''uses'''</tt>, то компилируются модули из этой секции ''слева направо''. | ||
Строка 222: | Строка 227: | ||
=== Стандартный системный модуль PABCSystem === | === Стандартный системный модуль PABCSystem === | ||
− | < | + | В каждой среде программирования на Pascal имеется стандартный системный модуль, который неявно ''первым'' подключается к любой программе или модулю. |
− | <source lang="Pascal"></source> | + | |
+ | Он содержит: | ||
+ | * стандартные константы | ||
+ | * типы | ||
+ | * подпрограммы | ||
+ | |||
+ | В Delphi — это ''<tt>System</tt>'', <br /> | ||
+ | в PascalABC.NET — ''<tt>PABCSystem</tt>''. | ||
+ | |||
+ | ''<u>Пример</u>.'' | ||
+ | <source lang="Pascal"> | ||
+ | program MyProgram; | ||
+ | [uses PABCSystem;] // подключается неявно | ||
+ | |||
+ | begin | ||
+ | writeln(sin(0)); | ||
+ | end. | ||
+ | </source> | ||
+ | <source lang="Pascal"> | ||
+ | program MyProgram; | ||
+ | uses A; // —> uses PABCSystem, A; | ||
+ | |||
+ | var sin: integer; | ||
+ | begin | ||
+ | writeln(PABCSystem.sin(0)); | ||
+ | end. | ||
+ | </source> | ||
+ | |||
+ | === Библиотеки === | ||
+ | <xh4> Сходства с модулем </xh4> | ||
+ | Библиотеки, как и модули: | ||
+ | * содержат группу взаимосвязанных подпрограмм | ||
+ | * находятся в откомпилированном файле | ||
+ | * предназначены для обращения к ним из различных программ | ||
+ | |||
+ | В ''Windows'' получили распространение библиотеки '''<tt>.dll</tt>''' (dynamically linked libraries). Они находятся либо в текущем каталоге приложения (''локальные''), либо в системном каталоге (''глобальные библиотеки''). | ||
+ | |||
+ | Глобальными библиотеками могут пользоваться одновременно несколько приложений. | ||
+ | |||
+ | <xh4> Отличия библиотек от модулей </xh4> | ||
+ | # При создании из модулей исполняемого файла линковщик помещает в него только те подпрограммы, которые используются (вызываются) в основной программе. <br />При компиляции же библиотеки в нее добавляются все подпрограммы, потому что неизвестно, какие подпрограммы потребуются конкретному приложению. <br /> <br />[[Изображение:Unit library.png|500px|Линковка модуля и библиотеки]] <br /> <br /> | ||
+ | # Библиотеки <tt>.dll</tt> при выполнении программы полностью загружаются в оперативную память. Если в них много неиспользуемых в программе функций, то память тратится непроизводительно. С этой точки зрения хорошо использовать <tt>.dll</tt>, которые используются одновременно несколькими программами. | ||
+ | # <tt>.dll</tt> легко заменить более свежей версией, просто скопировав нужный файл. | ||
+ | # <tt>.dll</tt> может быть написана и откомпилирована на одном языке, а обращаться можно из программ, написанных на других языках. Т.е. библиотеки обеспечивают '''''межъязыковое взаимодействие'''''. | ||
+ | |||
+ | <xh4> Библиотеки в PascalABC.NET </xh4> | ||
+ | '''''Синтаксис''''' | ||
+ | '''library''' <имя>; | ||
+ | '''interface''' | ||
+ | ... | ||
+ | '''implementation''' | ||
+ | ... | ||
+ | '''end'''. | ||
+ | |||
+ | '''Замечание.''' В библиотеках отсутствуют секции ''инициализации'' и ''финализации''. | ||
+ | |||
+ | Для подключения библиотеки используются конструкции: | ||
+ | '''#reference''' 'MyLib.dll' | ||
+ | '''{$reference''' MyLib.dll'''}''' | ||
− | < | + | '''Примечание.''' <tt>'''reference'''</tt> — директива компилятора. Указывает компилятору, что программа использует внешние библиотеки, расположенные в файле <tt>MyLib.dll</tt>. |
− | Документирующие комментарии /// | + | === Документирующие комментарии /// === |
+ | Документирующие комментарии предназначены для пояснения задач, решаемых подпрограммами. | ||
− | + | <xh4> Документирующие комментарии в PascalABC.NET </xh4> | |
+ | Отображаются в виде всплывающего окна при наведении указателя на имя подпрограммы. | ||
− | + | '''''Синтаксис''''' <br /> | |
+ | Чтобы воспользоваться документирующими комментариями, необходимо перед заголовком подпрограммы использовать следующую конструкцию: | ||
+ | '''/// ''' <текст комментария> | ||
− | + | Для того, чтобы активизировать документирующие комментарии в библиотеках, нужно использовать директиву | |
+ | '''#gendoc true''' |
Текущая версия на 08:16, 2 сентября 2013
Содержание
- 1 Модули
- 1.1 Введение
- 1.2 Синтаксис модуля
- 1.3 Семантические ограничения
- 1.4 Разделы инициализации и финализации модуля
- 1.5 Схема компиляции программы с модулями
- 1.6 Упрощенная структура модуля
- 1.7 Алгоритм поиска имен в модулях
- 1.8 Стандартный системный модуль PABCSystem
- 1.9 Библиотеки
- 1.10 Документирующие комментарии ///
Модули
Введение
Модуль — это совокупность взаимосвязанных процедур, функций, типов, переменных и констант, предназначенных для решения ряда однотипных задач, и помещенных в специальным образом оформленный файл.
Модули разбивают большой проект на относительно независимые части, при этом, каждая часть "живет своей жизнью": модуль, написанный для одного программного проекта, может быть использован в другом программном проекте.
Различают модули в виде исходных текстов и откомпилированные модули.
Откомпилированные модули уменьшают суммарное время компиляции и позволяют скрывать программный код от модификации.
Пример.
Модуль MyLib
unit MyLib;
interface // раздел интерфейса
const
MyPi = 3.14;
var
size: integer := 10;
function AddSquares(a, b: real): real;
procedure InvertPrint(a, b: integer);
implementation // раздел реализации
var i: integer;
function MySqr(a: real): real;
begin
Result := a * a;
end;
function AddSquares(a, b: real): real;
begin
Result := MySqr(a) + MySqr(b);
end;
procedure InvertPrint(a, b: integer);
begin
write(b, ' ', a);
end;
end. // конец модуля
Программа, подключающая модуль MyLib
uses MyLib;
var
n: integer;
begin
writeln(size);
writeln(AddSquares(3, 4));
InvertPrint(3,4);
end.
Модуль в языке Object Pascal состоит из двух разделов:
- раздел интерфейса
- раздел реализации
В разделе интерфейса описываются все
- переменные
- константы
- типы
- заголовки подпрограмм,
которые можно будет использовать в других модулях, подключающих данный.
В разделе реализации содержится
- реализация подпрограмм, заголовки которых приведены в разделе интерфейса
- описание вспомогательных констант, переменных, типов и подпрограмм,
которые нужны для реализации подпрограмм из раздела интерфейса и не видны из других модулей.
Данный принцип получил название принципа сокрытия информации.
Его преимущества:
- уменьшение количества информации, необходимой для понимания работы модуля
- сокрытие реализации от клиентов
- возможность легкого изменения реализации в следующих версиях без изменения интерфейса, т.е. без затрагивания интерфейса клиентов
- возможность скрыть программный код от клиентов, предоставив им лишь откомпилированную версию модуля
Синтаксис модуля
unit <имя модуля>; interface [uses <список модулей>;] <раздел описаний модуля: для п/п — только заголовки> implementation [uses <список модулей>;] <раздел описаний, где даны реализации п/п из раздела interface> [initialization <операторы>] begin | <операторы> [finalization end. <операторы>]
Семантические ограничения
- Модули, перечисленные в секции uses в разделах интерфейса и реализации не должны пересекаться
- циклическая зависимость между модулями в разделе интерфейса запрещена:
unit A; unit B; interface interface uses B; uses A;
- тем не менее, если A ссылается на B в разделе интерфейса, а B ссылается на A в разделе реализации, то это допустимо:
unit A; unit B; interface interface uses B; implementation uses A;
- потому что модули компилируются в два этапа:
- интерфейс
- реализация
Разделы инициализации и финализации модуля
unit A; основная программа ... initialization uses A; <операторы1> finalization begin <операторы2> <операторы3> end. end.
Операторы в разделе initialization модуля выполняются раньше тела основной программы,
а операторы в разделе finalization выполняются после основной программы.
Т.е. последовательность выполнения будет такой:
<операторы1> <операторы3> <операторы2>
Примечание. В разделе инициализации обычно инициализируются глобальные переменные из раздела интерфейса.
Пример.
unit A;
interface
var
RandomNumber: integer;
implementation
...
initialization
RandomNumber := Random(100);
end.
Схема компиляции программы с модулями
1. Компилируется файл основной программы.
2. Если в нем встречена секция uses, то компилируются модули из этой секции слева направо.
3. Каждый модуль компилируется так же, как и основная программа по пунктам 1-2:
- Если в модуле подключаются другие модули, то компилируются они,
- и так происходит до тех пор, пока компилятор не дойдет до модулей, не содержащих подключения других модулей.
4. По окончании компиляции модуля его откомпилированный вариант (.pcu в PascalABC.NET) записывается на диск.
5. После записи откомпилированного модуля на диск компилятор возвращается к основному модулю (вызывающему) или программе, и докомпилирует его до конца. Основная программа после компиляции хранится в оперативной памяти.
6. Первый этап компиляции закончен. Начинается заключительный этап компиляции — линковка (компоновка). Специальная программа — линковщик — собирает из откомпилированных модулей единый исполняемый файл (.exe в Windows).
Замечание 1. Ошибки могут происходить как на этапе компиляции, так и на этапе, собственно, линковки.
Замечание 2. Наличие откомпилированного файла модуля существенно ускоряет процесс компиляции (сводя его к процессу линковки).
Замечание 3. Если есть откомпилированные файлы модулей, то исходные тексты модулей можно удалить. При этом компилятор проанализирует, что данный модуль откомпилирован, и продолжит компиляцию дальше.
Замечание 4. Если файл модуля .pas создан после откомпилированного файла модуля (.pcu), то произойдет его перекомпиляция.
Замечание 5. При работе в интегрированной среде компилятор в первую очередь берет тексты модулей из открытых файлов и только затем смотрит файлы на диске.
Примечание 1. Файлы модулей могут храниться в другом каталоге относительно файла исходной программы. Тогда надо вместе с именем модуля указывать, в каком каталоге он хранится (тогда имя модуля и имя файла модуля могут не совпадать):
— Main ——————————— MyPr.pas | |— Modules | — a.pas | — b. pas
MyPr.pas program MyPr; uses A in 'Modules\a.pas'; B in 'Modules\b.pas';
Примечание 2. Откомпилированные файлы модулей по умолчанию создаются:
- в каталоге основной программы
- если установлен специальный путь в среде программирования для выходных файлов, то по этому пути
Кроме этого, стандартные откомпилированные модули хранятся в специальной папке, например, в PascalABC.NET — в папке \LIB. Если модуль претендует на звание стандартного, его можно туда поместить.
Упрощенная структура модуля
В PascalABC.NET можно использовать упрощенную структуру модуля:
unit <имя модуля>; <раздел описаний> [begin <операторы>] end.
В <разделе описаний> описываются типы, константы, переменные и подпрограммы.
Раздел begin + <операторы> соответствует разделу инициализации.
Алгоритм поиска имен в модулях
В разных модулях могут находиться объекты с одинаковыми именами, т.к. модуль является пространством имен.
Как же осуществляется поиск имен в модулях?
Правило 1. Имя вначале ищется в текущем модуле. Если не найдено, то в подключенных модулях секции uses справа налево.
Правило 2. Если нужно явно указать переменную из какого-то модуля, то перед ней ставится <имя модуля>.
Пример.
unit A;
uses B;
var n, m: integer;
...
end.
unit B;
var n, k, m: integer;
...
end.
program MyPr;
uses A, B;
var n: integer;
begin
n := 5; // из основной программы
k := 6; // из B
m := 7; // из B
A.n := 8; // из A
B.n := 9; // из B
A.m := 10; // из A
end.
Стандартный системный модуль PABCSystem
В каждой среде программирования на Pascal имеется стандартный системный модуль, который неявно первым подключается к любой программе или модулю.
Он содержит:
- стандартные константы
- типы
- подпрограммы
В Delphi — это System,
в PascalABC.NET — PABCSystem.
Пример.
program MyProgram;
[uses PABCSystem;] // подключается неявно
begin
writeln(sin(0));
end.
program MyProgram;
uses A; // —> uses PABCSystem, A;
var sin: integer;
begin
writeln(PABCSystem.sin(0));
end.
Библиотеки
<xh4> Сходства с модулем </xh4> Библиотеки, как и модули:
- содержат группу взаимосвязанных подпрограмм
- находятся в откомпилированном файле
- предназначены для обращения к ним из различных программ
В Windows получили распространение библиотеки .dll (dynamically linked libraries). Они находятся либо в текущем каталоге приложения (локальные), либо в системном каталоге (глобальные библиотеки).
Глобальными библиотеками могут пользоваться одновременно несколько приложений.
<xh4> Отличия библиотек от модулей </xh4>
- При создании из модулей исполняемого файла линковщик помещает в него только те подпрограммы, которые используются (вызываются) в основной программе.
При компиляции же библиотеки в нее добавляются все подпрограммы, потому что неизвестно, какие подпрограммы потребуются конкретному приложению.
- Библиотеки .dll при выполнении программы полностью загружаются в оперативную память. Если в них много неиспользуемых в программе функций, то память тратится непроизводительно. С этой точки зрения хорошо использовать .dll, которые используются одновременно несколькими программами.
- .dll легко заменить более свежей версией, просто скопировав нужный файл.
- .dll может быть написана и откомпилирована на одном языке, а обращаться можно из программ, написанных на других языках. Т.е. библиотеки обеспечивают межъязыковое взаимодействие.
<xh4> Библиотеки в PascalABC.NET </xh4> Синтаксис
library <имя>; interface ... implementation ... end.
Замечание. В библиотеках отсутствуют секции инициализации и финализации.
Для подключения библиотеки используются конструкции:
#reference 'MyLib.dll' {$reference MyLib.dll}
Примечание. reference — директива компилятора. Указывает компилятору, что программа использует внешние библиотеки, расположенные в файле MyLib.dll.
Документирующие комментарии ///
Документирующие комментарии предназначены для пояснения задач, решаемых подпрограммами.
<xh4> Документирующие комментарии в PascalABC.NET </xh4> Отображаются в виде всплывающего окна при наведении указателя на имя подпрограммы.
Синтаксис
Чтобы воспользоваться документирующими комментариями, необходимо перед заголовком подпрограммы использовать следующую конструкцию:
/// <текст комментария>
Для того, чтобы активизировать документирующие комментарии в библиотеках, нужно использовать директиву
#gendoc true