17. ПРОГРАММНЫЕ МОДУЛИ 17.1. Для чего нужны программные модули Известно, что при построении серьезной программы нельзя обойтись без процедур, которые заключают в себе ее отдельные части. Более крупными строительными единицами в Турбо-Паскале являются программные модули. Модуль имеет имя и может содержать описание многих процедур и функций, а также описания констант, типов данных и переменных. Каждый программный модуль транслируется отдельно. Оттранслированные модули объединяются в выполнимую программу, этот процесс называется сборкой. Однажды написанный и оттранслированный модуль можно многократно использовать в различных программах, что экономит силы программиста, сокращает время трансляции и предохраняет от искажений исходный текст модуля. Иногда это даже помогает сохранить авторские права на программный модуль. Чтобы подключить модуль к программе и сделать видимым его содержимое, достаточно упомянуть его имя в предложении USES имя модуля USES должно быть первым предложением программы. 17.2. Структура программного модуля Любой программный модуль построен по следующей схеме: UNIT имя модуля; INTERFACE интерфейсный раздел IMPLEMENTATI0N раздел реализации BEGIN раздел инициализации END. Имя модуля используется в предложении USES при подключении модуля к программе. В интерфейсном разделе перечисляется все, что должно быть видимым в модуле из программы, которая его использует. Константы, типы и переменные перечисляются в предложениях CONST, TYPE и VAR. Для процедур и функций даются только их заголовки. В разделе реализации находится полное описание всех процедур и функций, а также описание констант, типов и переменных, которые нужны для внутреннего использования и не должны быть видны снаружи. Заголовки процедур и функций могут или полностью совпадать с заголовками из интерфейсного раздела, или отличаться от них полным отсутствием параметров. Раздел инициализации содержит те операторы, что будут выполнены до начала программы, к которой подключен модуль. Если таких операторов нет, слово BEGIN писать не надо. Модуль следует хранить в одноименном файле с расширением PAS. 17.3. Пример модуля Ниже приведен пример модуля под названием Lists, который содержит средства работы со связанными списками из вещественных чисел. Модуль не ссылается на другие модули и не имеет раздела инициализации. UNIT Lists; INTERFACE uses crt; type PList = ^TElement; TElement = record { описание элемента списка } R: real; Next: PList; end; procedure Push (var List: PList; R: real); { добавляет к списку List число R } function Pop (var List: PList): real; { удаляет из списка List число R и возвращает его в программу} procedure Nul (var List: PList); { создает пустой список List} IMPLEMENTATION procedure Push (var List: PList; R: real); var P: PList; begin new (P); P^.R := R; P^.Next := List; List := P; end; function Pop (var List: PList): real; var P: PList; begin if List <> nil then begin Pop := List^.R; P := List; List := P^.Next; dispose (P); end {if}; end; procedure Nul (var List: PList); begin List := nil; end; END. Вот программа, которая использует модуль Lists. Она создает пустой список, добавляет к нему три числа, потом одно удаляет и выводит на экран: uses Lists; var L: PList; R: real; begin Nul (L); Push (L, 1.0); Push (L, 2.0); Push (L, 3.0); writein (Pop (L)); end. 17.4. Ссылки на модули Модуль, как и программа, может использовать объекты, описанные в других модулях. Если эти объекты нужны в интерфейсном разделе, то он должен начинаться с предложения USES, в котором перечисляются имена всех необходимых модулей. Если на объекты есть ссылки только из раздела реализации, предложение USES может находиться в разделе реализации. Предположим, в программе в предложении USES есть имя модуля А, который ссылается на модуль В. Это не означает, что в программе доступны объекты из В. Если в этом есть необходимость, в программе следует перечислить имена обоих модулей в предложении USES. Взаимные ссылки двух модулей возможны только из разделов реализации. Unit A; Unit B; Uses B; Uses A; Рис. 17.1 В разных модулях могут быть описаны одноименные объекты, например, и в модуле А и в модуле В может быть определена переменная V. Чтобы различить две такие переменные, к их именам добавляют имя модуля: A.V или B.V. 17.5. Стандартные модули ТП Основная часть средств ТП расположена в стандартных модулях, которые поставляются в оттранслированном виде вместе с компилятором. Здесь мы рассмотрим некоторые из них. В модуле SYSTEM содержатся средства ввода-вывода в текстовые и типизированные файлы, процедуры и функции для работы со строками, вещественными числами и динамической памятью. Модуль SYSTEM бывает нужен так часто, что он автоматически подсоединяется ко всем программам и модулям и вам незачем делать это явно. В модуле CRT сосредоточены средства управления дисплеем в текстовом режиме, клавиатурой, динамиком. При помощи имеющихся в нем процедур можно изменять цвета, выводить информацию в любом месте экрана, создавать окна, воспроизводить звуковые тоны различной высоты и длительности, обрабатывать расширенные коды клавиш. Модуль DOS открывает доступ к возможностям операционной системы MS DOS. В нем находятся процедуры обработки даты и времени дня, анализа состояния магнитных дисков, средства работы со справочниками и отдельными файлами. Благодаря этому модулю из программы можно вызвать другую программу или сделать программу резидентной. Можно выполнить любую существующую процедуру обработки прерывания или написать свою собственную. Модуль GRAPH содержит более 50 графических процедур, которые позволяют воспроизводить на экране точки, отрезки, многоугольники, окружности и другие фигуры различных цветов и размеров. Есть средства для разнообразных видов закрашивания и вывода текста в графическом режиме. Возможна работа с битовыми образами экрана и его частей. Работа с разнообразными адаптерами обеспечивается набором графических драйверов, которые находятся в отдельных файлах. Заметим, что модули SYSTEM, CRT и DOS обычно находятся в составе библиотечного файла TURBO.TPL, а модуль GRAPH представляет собой отдельный файл.