Руководство по языку B.Pascal 7

       

Перекрестные ссылки на модули


Размещение в секции реализации оператора 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 и модуля В не зависят друг от друга (и, следовательно, строго соб- людаются правила Паскаля, касающиеся порядка описания).

В случае взаимозависимости интерфейсных секций модулей вы получите ошибку из-за перекрестных ссылок.


Содержание раздела