Размещение в секции реализации оператора uses позволяет
"скрыть" внутренние детали модуля, поскольку используемые в сек-
ции реализации модули оказываются "невидимыми" для того, кто этот
модуль использует. Более важным, однако, является то, что это
позволяет вам строить взаимозависимые модули.
В следующей программе показаны два модуля, которые "исполь-
зуют" друг друга. Основная программа Circular использует модуль с
именем Display. Модуль Display содержит в своей интерфейсной сек-
ции одну программу WriteXY, которая имеет три параметра: пару ко-
ординат (x,y) и сообщение для вывода на экран. WriteXY перемещает
курсор в точку (x,y) и выводит там сообщение. В противном случае
она вызывает простую программу обработки ошибки.
Пока мы не видим здесь ничего интересного: процедура WriteXY
просто используется вместо процедуры Write. Однако далее, когда
программа обработки ошибки будет выводить сообщение на экран, на-
чинаются перекрестные ссылки (ведь при этом она снова использует
WriteXY). Таким образом, мы имеем процедуру WriteXY, вызывающую
процедуру обработки ошибки SwapError, которая в свою очередь вы-
зывает WriteXY для вывода сообщения на экран. Если у вас уже от
всего этого закружилась голова, не беда. Давайте рассмотрим ис-
ходный код в примере и увидим, что все это не столь уж запутано.
Основная программа Circular очищает экран и выполняет три
обращения к процедуре WriteXY:
program Circular;
{ выводит текст, используя WriteXY }
uses
WinCrt, Display;
begin
ClrScr;
WriteXY(1, 1, 'Левый верхний угол экрана');
WriteXY(100, 100, 'За пределами экрана');
WriteXY(81 - Lenght('Снова в экран..'), 15,
'Снова в экран..');
end.
Взгляните на координаты (x,y) при втором обращении к проце-
дуре WriteXY. В точке с координатами (100,100) на 80х25-символь-
ном экране вывести текст невозможно. Давайте теперь посмотрим,
как работает процедура WriteXY. Далее приведен текст исходного
кода модуля Display, в котором содержится процедура WriteXY. Если
координаты (x,y) являются допустимыми, она выводит на экран сооб-
щение. В противном случае она выводит сообщение об ошибке.
unit Display;
{ содержит простую программу вывода информации на экран }
interface
procedure WriteXY(X,Y : integer, Message : string);
implementation
uses
Crt, Error;
procedure WriteXY(X,Y : integer, Message : string);
begin
if (X in [1..80] and Y in [1..25] then
begin
Goto(X,Y);
Write(Message);
end;
else
ShowError('Неверные координаты в процедуре WriteXY');
end;
end.
Процедура ShowError, вызываемая в процедуре WriteXY, показа-
на в приведенном далее исходном коде модуля Error. Она всегда вы-
водит сообщение об ошибке на 25-й строке экрана.
unit Error;
{ содержит простую программу сообщения об ошибке }
interface
procedure ShowError(ErrMsg : string);
implementation
uses
Display;
procedure ShowError(ErrMsg :string);
begin
WriteXY(1,25, 'Ошибка: '+ ErrMsg);
end;
end.
Обратите внимание, что операторы uses в секции реализации
обоих модулей (Display и Error) ссылаются друг на друга. Эти два
модуля могут ссылаться друг на друга в секции реализации благода-
ря тому, что Borland Pascal может для обеих модулей выполнять
полную компиляцию интерфейсных секций. Другими словами, компиля-
тор воспринимает ссылку на частично скомпилированный модуль A в
секции реализации модуля В, если интерфейсные секции модуля A и
модуля В не зависят друг от друга (и, следовательно, строго соб-
B.Pascal 7 & Objects/LR - 179 -
людаются правила Паскаля, касающиеся порядка описания).
В случае взаимозависимости интерфейсных секций модулей вы
получите ошибку из-за перекрестных ссылок.