Локализация имен
Модули
Концепция модульного программирования
Концепцию модульного программирования можно сформулировать в виде нескольких понятий и положений:
· Функциональная декомпозиция задачи - разбиение большой задачи на ряд более мелких, функционально самостоятельных подзадач - модулей. Модули связаны между собой только по входным и выходным данным.
· Модуль - основа концепции модульного программирования. Каждый модуль в функциональной декомпозиции представляет собой "черный ящик" с одним входом и одним выходом. Модульный подход позволяет безболезненно производить модернизацию программы в процессе ее эксплуатации и облегчает ее сопровождение. Дополнительно модульный подход позволяет разрабатывать части программ одного проекта на разных языках программирования, после чего с помощью компоновочных средств объединять их в единый загрузочный модуль.
· Реализуемые решения должны быть простыми и ясными. Если назначение модуля непонятно, то это говорит о том, что декомпозиция начальной или промежуточной задачи была проведена недостаточно качественно. В этом случае необходимо еще раз проанализировать задачу и, возможно, провести дополнительное разбиение на подзадачи. При наличии сложных мест в проекте их нужно подробнее документировать с помощью продуманной системы комментариев. Этот процесс нужно продолжать до тех пор, пока действительно не удастся добиться ясного понимания назначения всех модулей задачи и их оптимального сочетания.
· Назначение всех переменных модуля должно быть описано с помощью комментариев по мере их определения.
Литература
1) М.М. Бежанова, Л.А. Москвина. Практическое программирование. Приемы создания программ на языке Паскаль. М.: Научный Мир, 2000, 270 с. ISBN 5-89176-112-2
2) Истомин Е.П., Новиков В.В., Новикова М.В. Высокоуровневые методы информатики и программирования: Учебник. - СПб. ООО "Адреевский издательский дом", 2006 г. - 228 с. ISBN 5-902894-07-7
Во многих случаях, при разработке программ, размещение некоторой части переменных, констант, функций целесообразно проводить в модулях (например, библиотека функций). Модуль выступает как библиотека, которую можно употреблять во многих программах, и каждая из них берет только то, что ей требуется.
Модуль - это автономно компилируемая программная единица, включающая в себя различные компоненты интерфейсного раздела, и, возможно, некоторые исполняемые операторы инициирующего раздела. Реализация процедур и функций модуля описывается в исполняемом разделе.
Каждый модуль описывается в отдельном файле. Формат модуля:
unit <идентификатор модуля>; interface //интерфейсная часть <описание типов, констант, переменных, подпрограмм> implementation //исполняемая часть <реализация предоставляемых модулем подпрограмм, описание локальных типов, констант, переменных, подпрограмм> begin end.[initialization // инициирующая часть <раздел инициализации>finalization //завершающая часть <раздел завершения>]Заголовок модуля состоит из зарезервированного слова unitи идентификатора. Идентификатор модуля должен быть уникальным. Пример: unit MyModule;
Модуль должен быть помещен в файл, имя которого совпадает с именем модуля, а его расширение должно быть .PAS. <идентификатор модуля> должен совпадать с именем файла, в котором хранится данный модуль.
Все компоненты, описанные в разделе interface, являются доступными для всех программ и модулей, использующих данный модуль. Интерфейс может содержать следующие разделы:
• раздел объявления используемых модулей;
• раздел объявления констант;
• раздел объявления типов;
• раздел объявления переменных;
• раздел объявления процедур и функций
Все разделы интерфейсной части, кроме раздела объявления используемых модулей, могут идти в любой последовательности; можно создавать несколько однотипных разделов.
При описании подпрограмм, в разделе interface приводится только заголовок подпрограммы. В разделе implementation заголовок каждой из подпрограмм повторяется, после чего происходит описание ее реализации. При повторении заголовка допускается опускание параметров подпрограммы. Если параметры не опускаются, то заголовок должен в точности соответствовать заголовку раздела interface. Исполнительная часть включает все подпрограммы модуля. Она может также включать локальные метки, константы, типы и переменные, недоступные для других программных единиц. Начинается исполнительная часть словом implementation,а завершается либо началом секции инициализации, если она есть, либо словом end.
Раздел инициализации, чаще всего, используется для задания начальных значений переменных, описанных в модуле. Выполнение данного раздела производится только один раз, даже если в разрабатываемой программе имеется несколько ссылок на данный модуль.
Примечание: в среде Delphi раздел инициализации можно начать используя ключевое слово initialization. Кроме того, после данного раздела может идти раздел завершения (ключевое слово finalization).
Для подключения модуля к основной программе, а также для использования одним модулем другого, применяется ключевое слово uses, после которого указывается список идентификаторов подключаемых модулей.
При использовании одного модуля другим, подключение модулей с использованием ключевого слова uses может производиться как в разделе interface, так и в разделе implementation. Однако не допускается взаимное подключение модулей через разделы interface. При необходимости взаимного подключения модулей, как минимум одно из подключений должно располагаться в разделе implementation. Выбор вариантов подключения производится на основе того, в каком из модулей необходим доступ к ресурсам другого модуля в разделе interface. В случае, когда обоим модулям требуется подключение в разделе interface, создается третий модуль, в который переносятся взаимно-зависимые части.
Являясь независимой программной единицей, модуль имеет свое пространство идентификаторов. Если в программе или модуле, использующем другой модуль, имеется одноименный идентификатор, то ему отдается предпочтение. Для обращения к идентификатору подключаемого модуля, в этом случае, требуется уточнение, записываемое как:
<идентификатор модуля>.<идентификатор компонента>Пример:
unit Modul1;interface type Mas : array[1..100] of integer; Var X : integer; procedure InputMas(var A : Mas; n : integer); implementation procedure InputMas(var A : Mas; n : integer); begin end; beginX := 1; end. program Programsuses Modul1; type Mas : array[1..100] of integer; Var X,n : integer; A : Mas; В : Modul1.Mas;begin InputMas(A,n); {Ошибка} InputMas(B,n); {Нет ошибки} X := 5; {^пользуется переменная основной программы} Modul1.X := 10; {Используется переменная модуля}End.При использовании подпрограмм возникает возможность использования в них идентификаторов, которые уже используются в основной программе. Однако при этом требуется четкое представление того, какой из идентификаторов будет использоваться в том или ином фрагменте программы.
Общим правилом для определения доступности идентификаторов является следующее: доступны всегда идентификаторы, расположенные выше по описанию и находящиеся в цепочки вложенности процедур и функций. Таким образом, возможно, например, обращение из процедуры к глобальным переменным основной программы, описанным выше, к переменным других процедур, в которые вложена данная, но невозможно обращение из основной программы к переменным любой из процедур.
Рассмотрим пример:
program a1; var A,B : integer; procedure P1; var A,B : integer; procedure P1_1; var A,C : integer; begin {Доступные переменные} A := 1; {переменная процедуры P1 1} C := 2; {переменная процедуры P1 1} B := 3; {переменная процедуры P1} a1.A := 4; {переменная основной программы} a1.B := 5; {переменная основной программы} { Недоступные переменный} A из процедуры P1 A,D из процедуры P1_2 E,F из основной программы end; {P1_1} procedure P1_2; var A,D : integer; begin {Доступные переменные} A := 1; {переменная процедуры P1 2} D := 2; {переменная процедуры P1 2} В := 3; {переменная процедуры P1} a1.A := 4; {переменная основной программы} a1.B := 5; {переменная основной программы} {Недоступные переменный} A из процедуры P1 А, С из процедуры P1_1 E,F из основной программы end; {P1_2} begin { Доступные переменные} А := 1; {переменная процедуры P1} В := 2; {переменная процедуры P1} a1.A := 3; {переменная основной программы} a1.B := 4; {переменная основной программы} { Недоступные переменный} А, С из процедуры P1_1 A,D из процедуры P1_2 E,F из основной программы end; {P1}Var E,F : integer; begin{ Доступные переменные} A := 1; { переменная основной программы} В := 2; { переменная основной программы} E := 3; { переменная основной программы} F := 4; { переменная основной программы}{ Недоступные переменные} А,В из процедуры P1 А,С из процедуры P1_1 A,D из процедуры P1_2 end. {основная программа}Таким образом, в передах видимости оказываются только переменные, описанные выше в основной программе, либо в текущей процедуре.