Основы программирования — Осенний семестр; Михалкович С.С.; 2008; V — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Модули)
 
(не показано 11 промежуточных версий 2 участников)
Строка 1: Строка 1:
 
[[Категория:Основы программирования]]
 
[[Категория:Основы программирования]]
==Модули==
+
[[Страница курса Основы программирования|К основной странице курса]]
 +
== Модули ==
 
=== Введение ===
 
=== Введение ===
 
'''Модуль''' — это совокупность взаимосвязанных процедур, функций, типов, переменных и констант,  
 
'''Модуль''' — это совокупность взаимосвязанных процедур, функций, типов, переменных и констант,  
 
предназначенных для решения ряда однотипных задач, и помещенных в специальным образом оформленный файл.
 
предназначенных для решения ряда однотипных задач, и помещенных в специальным образом оформленный файл.
  
Модули разбивают большой проект на относительно независимые части, при этом, каждая часть "живет своей жизнью": модуль, написанный для одного программного проекта может быть использован в другом программном проекте.
+
Модули разбивают большой проект на относительно независимые части, при этом, каждая часть "живет своей жизнью": модуль, написанный для одного программного проекта, может быть использован в другом программном проекте.
  
Различают модули в виде '''''исходных текстов''''' и '''''откомпилированные модули'''''.
+
Различают модули в виде '''''исходных текстов''''' и '''''откомпилированные модули'''''. <br />
<br>Откомпилированные модули уменьшают суммарное время компиляции и позволяют ''скрывать программный код от модификации''.
+
Откомпилированные модули уменьшают суммарное время компиляции и позволяют ''скрывать программный код от модификации''.
  
'''Пример.'''
+
''<u>Пример</u>.'' <br />
:Модуль ''MyLib''
+
<u>Модуль <tt>MyLib</tt></u>
<source lang="Pascal">unit MyLib;
+
<source lang="Pascal">
 +
unit MyLib;
  
 
interface      // раздел интерфейса
 
interface      // раздел интерфейса
Строка 28: Строка 30:
 
function MySqr(a: real): real;
 
function MySqr(a: real): real;
 
begin
 
begin
   result := a * a;
+
   Result := a * a;
 
end;
 
end;
  
 
function AddSquares(a, b: real): real;
 
function AddSquares(a, b: real): real;
 
begin
 
begin
   result := MySqr(a) + MySqr(b);
+
   Result := MySqr(a) + MySqr(b);
 
end;
 
end;
  
Строка 41: Строка 43:
 
end;
 
end;
  
end.            // конец модуля</source>
+
end.            // конец модуля
 +
</source>
  
:Программа, подключающая модуль ''MyLib''
+
<u>Программа, подключающая модуль <tt>MyLib</tt></u>
<source lang="Pascal">uses MyLib;
+
<source lang="Pascal">
 +
uses MyLib;
  
 
var
 
var
Строка 53: Строка 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>которые можно будет использовать в других модулях, подключающих данный.
+
* ''константы''
 +
* ''типы''
 +
* ''заголовки подпрограмм'',
 +
которые можно будет использовать в других модулях, подключающих данный.
  
В разделе '''реализации''' содержится  
+
В разделе ''реализации'' содержится  
<br>''реализация подпрограмм'',
+
* ''реализация подпрограмм'', заголовки которых приведены в разделе интерфейса
<br>заголовки которых приведены в разделе интерфейса, а также
+
* описание ''вспомогательных'' констант, переменных, типов и подпрограмм,
<br>описание ''вспомогательных констант, переменных, типов и подпрограмм'',
+
которые нужны для реализации подпрограмм из раздела интерфейса и не видны из других модулей.
<br>которые нужны для реализации подпрограмм из раздела интерфейса и не видны из других модулей.
 
  
Данный принцип получил название '''принципа сокрытия информации'''.
+
Данный принцип получил название '''принципа сокрытия информации'''. <br />
<br>Его ''преимущества'':
+
Его '''преимущества''':
*уменьшение количества информации, необходимой для понимания работы модуля;
+
* уменьшение количества информации, необходимой для понимания работы модуля
*сокрытие реализации от клиентов;
+
* сокрытие реализации от клиентов
*возможность легкого изменения реализации в следующих версиях без изменения интерфейса, т.е. без затрагивания интерфейса клиентов;
+
* возможность легкого изменения реализации в следующих версиях без изменения интерфейса, т.е. без затрагивания интерфейса клиентов
*возможность скрыть программный код от клиентов, предоставив им лишь откомпилированную версию модуля;
+
* возможность скрыть программный код от клиентов, предоставив им лишь откомпилированную версию модуля
  
<small>'''Лекция 14'''</small>
 
 
=== Синтаксис модуля ===
 
=== Синтаксис модуля ===
 
  '''unit''' <имя модуля>;
 
  '''unit''' <имя модуля>;
Строка 97: Строка 102:
  
 
=== Семантические ограничения ===
 
=== Семантические ограничения ===
*Модули, перечисленные в секции <tt>'''uses'''</tt> в разделах интерфейса и реализации не должны пересекаться;
+
* Модули, перечисленные в секции <tt>'''uses'''</tt> в разделах интерфейса и реализации не должны пересекаться
*''циклическая зависимость'' между модулями в разделе интерфейса '''запрещена''':
+
* ''циклическая зависимость'' между модулями в разделе интерфейса '''запрещена''':
 
  '''unit''' A;        '''unit''' B;
 
  '''unit''' A;        '''unit''' B;
 
  '''interface'''      '''interface'''
 
  '''interface'''      '''interface'''
Строка 108: Строка 113:
 
                 '''uses''' A;
 
                 '''uses''' A;
 
:потому что модули '''''компилируются в два этапа''''':
 
:потому что модули '''''компилируются в два этапа''''':
:*интерфейс
+
:* интерфейс
:*реализация
+
:* реализация
  
 
=== Разделы инициализации и финализации модуля ===
 
=== Разделы инициализации и финализации модуля ===
Строка 120: Строка 125:
 
  '''end'''.                          '''end'''.
 
  '''end'''.                          '''end'''.
  
Операторы в разделе '''<tt>initialization</tt>''' модуля выполняются ''раньше'' тела основной программы,  
+
Операторы в разделе '''<tt>initialization</tt>''' модуля выполняются ''раньше'' тела основной программы, <br />
<br /> а операторы в разделе <tt>'''finalization'''</tt> выполняются''после'' основной программы.
+
а операторы в разделе <tt>'''finalization'''</tt> выполняются ''после'' основной программы.
  
 
Т.е. последовательность выполнения будет такой:
 
Т.е. последовательность выполнения будет такой:
Строка 127: Строка 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
Строка 144: Строка 151:
  
 
=== Схема компиляции программы с модулями ===
 
=== Схема компиляции программы с модулями ===
<Здесь будет рисунок>
+
[[Изображение:Схема компиляции модуля.png|500px|thumb|right|Схема компиляции программы с модулями]]
 
 
 
1. Компилируется файл основной программы.
 
1. Компилируется файл основной программы.
 
<br />2. Если в нем встречена секция <tt>'''uses'''</tt>, то компилируются модули из этой секции ''слева направо''.
 
<br />2. Если в нем встречена секция <tt>'''uses'''</tt>, то компилируются модули из этой секции ''слева направо''.
Строка 221: Строка 227:
  
 
=== Стандартный системный модуль PABCSystem ===
 
=== Стандартный системный модуль PABCSystem ===
<xh4></xh4>
+
В каждой среде программирования на 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'''}'''
  
<small>'''Лекция 15'''</small>
+
'''Примечание.''' <tt>'''reference'''</tt> — директива компилятора. Указывает компилятору, что программа использует внешние библиотеки, расположенные в файле <tt>MyLib.dll</tt>.
  
Документирующие комментарии ///
+
=== Документирующие комментарии /// ===
 +
Документирующие комментарии предназначены для пояснения задач, решаемых подпрограммами.
  
Библиотеки. Отличие библиотек от модулей. Подключение библиотек в PascalABC.NET.
+
<xh4> Документирующие комментарии в PascalABC.NET </xh4>
 +
Отображаются в виде всплывающего окна при наведении указателя на имя подпрограммы.
  
Перечислимый и диапазонный типы. Стандартные функции Ord Pred Succ. Стандартные процедуры Inc Dec.
+
'''''Синтаксис''''' <br />
 +
Чтобы воспользоваться документирующими комментариями, необходимо перед заголовком подпрограммы использовать следующую конструкцию:
 +
'''/// ''' <текст комментария>
  
Использование перечислимого типа в for и case.
+
Для того, чтобы активизировать документирующие комментарии в библиотеках, нужно использовать директиву
 +
'''#gendoc true'''

Текущая версия на 08:16, 2 сентября 2013

К основной странице курса

Модули

Введение

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

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

Различают модули в виде исходных текстов и откомпилированные модули.
Откомпилированные модули уменьшают суммарное время компиляции и позволяют скрывать программный код от модификации.

Пример.
Модуль 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>

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

    Линковка модуля и библиотеки

  2. Библиотеки .dll при выполнении программы полностью загружаются в оперативную память. Если в них много неиспользуемых в программе функций, то память тратится непроизводительно. С этой точки зрения хорошо использовать .dll, которые используются одновременно несколькими программами.
  3. .dll легко заменить более свежей версией, просто скопировав нужный файл.
  4. .dll может быть написана и откомпилирована на одном языке, а обращаться можно из программ, написанных на других языках. Т.е. библиотеки обеспечивают межъязыковое взаимодействие.

<xh4> Библиотеки в PascalABC.NET </xh4> Синтаксис

library <имя>;
interface
...
implementation
...
end.

Замечание. В библиотеках отсутствуют секции инициализации и финализации.

Для подключения библиотеки используются конструкции:

#reference 'MyLib.dll'
{$reference MyLib.dll}

Примечание. reference — директива компилятора. Указывает компилятору, что программа использует внешние библиотеки, расположенные в файле MyLib.dll.

Документирующие комментарии ///

Документирующие комментарии предназначены для пояснения задач, решаемых подпрограммами.

<xh4> Документирующие комментарии в PascalABC.NET </xh4> Отображаются в виде всплывающего окна при наведении указателя на имя подпрограммы.

Синтаксис
Чтобы воспользоваться документирующими комментариями, необходимо перед заголовком подпрограммы использовать следующую конструкцию:

///  <текст комментария>

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

#gendoc true