Локализация имен

Модули

Концепция модульного программирования

Концепцию модульного программирования можно сформулировать в виде нескольких понятий и положений:

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

· Модуль - основа концепции модульного программирования. Каждый модуль в функциональной декомпозиции представляет собой "черный ящик" с одним входом и одним выходом. Модульный подход позволяет безболезненно производить модернизацию программы в процессе ее эксплуатации и облегчает ее сопровождение. Дополнительно модульный подход позволяет разрабатывать части программ одного проекта на разных языках программирования, после чего с помощью компоновочных средств объединять их в единый загрузочный модуль.

· Реализуемые решения должны быть простыми и ясными. Если назначение модуля непонятно, то это говорит о том, что декомпозиция начальной или промежуточной задачи была проведена недостаточно качественно. В этом случае необходимо еще раз проанализировать задачу и, возможно, провести дополнительное разбиение на подзадачи. При наличии сложных мест в проекте их нужно подробнее документировать с помощью продуманной системы комментариев. Этот процесс нужно продолжать до тех пор, пока действительно не удастся добиться ясного понимания назначения всех модулей задачи и их оптимального сочетания.

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

Литература

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. {основная программа}

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