Теория
Мы уже не однократно использовали в своих программах модуль CRT и пару раз модуль Graph. Наверняка вы догадываетесь, что можно самим написать модуль. Разработка модулей существенно повысит вашу производительность как программиста. Например написав однажды кучу функций можно собрать их в один модуль и не копировать из файла в файл. Хочу оговориться, что модули это исключительна фишка Турбо Паскаля. В стандартном Паскале такого нет.
Модули так же полезны, если код не влезает в 64 Кб (это актуально только для ДОС программ), т.к. компилятор Турбо Паскаля загоняет текст модуля в отдельный сегмент.
По своей сути модуль представляет из себя ту же программу с несколько иным началом. Структура модуля такова:
UNIT имя;
INTERFACE
интерфейсная часть
IMPLEMENTATION
исполняемая часть
BEGIN
часть инициализации
END.
Начнём по порядку. ИМЯ - задаёт имя модуля (это то, которое мы потом будем объявлять в USES). Для того что бы избежать лишних проблем следует называть модуль и файл с его кодом одним именем. Т.е. если мы хотим назвать модуль так: unit myunit;
то текст его должен распологаться в файле с именем myunit.pas.
Интерфейсная часть несёт в себе описание типов, переменных, констант, подпрограмм, которые можно будет использовать (вызывать) из головной программы. При описании подпрограмм нужно написать просто их заголовок. Например начнём писать простенький модуль для работы с комплексными числами. (для тех кто в танке - комплексные числа - это числа вида a + b*i, где i число, такое что i2 = -1, a и b - вещественные числа... вообщем литературу на эту тему найти легко, было бы желание). Для этого опишем запись с полями re и im (это a и b) и заголовок процедуры для сложения 2-х комплексных чисел.
unit Cmplx;
interface
type
complex = record
re, im : real;
end;
procedure AddComplex (x, y : complex; var z : complex);
Итак теперь в основной программе, подключив наш модуль, мы можем объявить переменные типа complex и вызывать процедуру AddComplex. Следует так же отметить (ведь наши программы пока для ДОСа), что все переменные объявленные в интерфейсной части модуля и все переменные основной программы помещаются в единный сегмент данных и следовательно не могут превышать 64 Кб.
Переходим к исполняемой части. В ней должно содержаться описание подпрограмм, объявленных в интерфейсной части. Так же можно помещать локальные для модуля объекты (т.е. к ним нельзя обратиться из головной программы) - типы, константы, подпрограммы, переменные. Продолжим наш модуль:
unit Cmplx;
interface
type
complex = record
re, im : real;
end;
procedure AddComplex (x, y : complex; var z : complex);
implementation
procedure AddComplex;
begin
z.re := x.re + y.re;
z.im := x.im + y.im
end;
Обратите внимание на объявление процедуры AddComplex в исполняемой части модуля. Очередная халява - можно опускать список параметров (и тип результата для функции), так как они уже описаны в интерфейсной части. При этом халява не обязательная - вы вполне можете написать полный заголовок.
Переходим к последней части - части инициализации. Она может быть, а может и не быть. Если она есть - тогда обрамляется begin-end. Если её нет, тогда просто пишется end. (с точкой!!). В части инициализации помещается код, который выполняется до передачи управления главной программы. Например здесь программист может присвоить переменным модуля какие-то стартовые значения. В нашем модуле нет никаких тайных махинации и поэтому мы можем опустить инициализацию и вот он - наш первый законченный модуль:
unit Cmplx;
interface
type
complex = record
re, im : real;
end;
procedure AddComplex (x, y : complex; var z : complex);
implementation
procedure AddComplex;
begin
z.re := x.re + y.re;
z.im := x.im + y.im
end;
end.
Ещё один важный момент - если нечего инициализировать, то тогда лучше вообще не писать часть инициализации (т.е. слово begin) т.к. получится так называемый пустой оператор. Что может в некоторых случаях привести к проблемам.
Давайте напишем модуль с инициализацией и скрытой переменной:
unit some;
interface
procedure iplus;
implementation
uses CRT;
var
i : integer;
procedure iplus;
begin
i := i + 1;
writeLn ('I = ', i)
end;
begin
randomize;
i := random (256);
writeLn ('Start I = ', i)
end.
i - это переменная, доступная только внутри модуля! Тепрь напишем головную программу, использующую этот самый модуль:
program test;
uses some;
begin
writeLn ('Yo-ho-ho!');
iplus;
iplus;
iplus
end.
Запускаем и что мы видим?