ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 11

                             ГЛАВА 9.

                        ПРОГРАММЫ И МОДУЛИ.


                       Синтаксис программы.

     Программа в  Turbo  Pascal имеет такой же вид,  как объявление
процедуры, за исключением  заголовка  программы  и  необязательного
предложения uses.


программа
  і      ЪДДДДДДДДДї   ЪДї                        ЪДДДДї   ЪДї
  АДДДВДцізаголовокГДДці;ГДДДДВДДДДДДДДДДДДДДДДДДціблокГДДці.ГДДц
      і  іпрограммыі   АДЩ ш  і  ЪДДДДДДДДДДДї ш  АДДДДЩ   АДЩ
      і  АДДДДДДДДДЩ       і  АДціпредложениеГДЩ
      АДДДДДДДДДДДДДДДДДДДДЩ     і   uses    і
                                 АДДДДДДДДДДДЩ


                       Заголовок программы.

     Заголовок программы определяет имя программы и ее параметры.


заголовок программы
 і
 і   ЪДДДДДДДї   ЪДДДДДДДДДДДДДї
 АДДціprogramГДДціидентификаторГДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДц
     АДДДДДДДЩ   АДДДДДДДДДДДДДЩ і  ЪДї   ЪДДДДДДДДДї   ЪДї ш
                                 АДці(ГДДціпараметрыГДДці)ГДЩ
                                    АДЩ   іпрограммыі   АДЩ
                                          АДДДДДДДДДЩ

                          ЪДДДДДДДДДДДДДДДї
параметры программы  ДДДДці   список      ГДДДДц
                          іидентификаторові
                          АДДДДДДДДДДДДДДДЩ


     Если заголовок  программы  присутствует,  то он является чисто
декоративной деталью и игнорируется компилятором.


                         Предложение uses.

     Предложение uses   идентифицирует   все  модули,  используемые
программой,  включая непосредственно используемые модули и  модули,
используемые этими модулями.


                     ЪДДДДї      ЪДДДДДДДДДДДДДї      ЪДї
предложение uses ДДДціusesГДДВДДціидентификаторГДДДДДці;ГДДДц
                     АДДДДЩ  і   АДДДДДДДДДДДДДЩ  ш   АДЩ
                             і      ЪДї           і
                             АДДДДДці,ГДДДДДДДДДДДЩ
                                    АДЩ

     Модуль System   всегда   используется   автоматически.  System
реализует весь   нижний   уровень,   поддержку   программ   времени
выполнения для  поддержки  таких средств,  как файловый ввод/вывод,
обработка  строк,  операции  с  плавающей   запятой,   динамическое
распределение памяти и других. Кроме System, Turbo Pascal реализует
многие стандартные модули,  такие как Printer,  Dos и Crt.  Они  не
используются автоматически:  Вы  должны  обязательно  включить их в
предложение uses, например:

     uses Dos, Crt; {теперь получен доступ к средствам Dos и Crt}

     Порядок перечисления модулей  в  uses  определяет  порядок  их
инициализации. См. раздел "Раздел инициализации".


                        Cинтаксис модулей.

     Модули являются   в   Turbo    Pascal    основой    модульного
программирования.  Они используются для создания библиотек, которые
могут  включаться  в  различные  программы  (при  этом   становится
необязательным  иметь в наличии исходный код),  а большие программы
могут подразделяться на логически связанные модули.


              ЪДДДДДДДДДї   ЪДї   ЪДДДДДДДДДДї
модуль  ДДДДДцізаголовокГДДці;ГДДціинтерфейс-ГДДДї
              і модуля  і   АДЩ   іный разделі   і
              АДДДДДДДДДЩ         АДДДДДДДДДДЩ   і
            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
            і  ЪДДДДДДДДДДї    ЪДДДДДДДДДДДДДї   ЪДї
            АДці раздел   ГДДДці раздел      ГДДці.ГДДц
               іреализацииі    іинициализацииі   АДЩ
               АДДДДДДДДДДЩ    АДДДДДДДДДДДДДЩ



                         Заголовок модуля.

     В заголовке модуля определяется имя модуля


                     ЪДДДДї   ЪДДДДДДДДДДДДДДДДДДДДї
заголовок модуля ДДДціunitіДДціидентификатор модуляіДДДДц
                     АДДДДЩ   АДДДДДДДДДДДДДДДДДДДДЩ


     Имя модуля используется при ссылке  на  модуль  в  предложении
uses. Это   имя должно быть уникальным,  так как два модуля с одним
именем не могут использоваться одновременно.


                       Интерфейсный раздел.

     В интерфейсном  разделе  объявляются   те   константы,   типы,
переменные,  процедуры и функции,  которые являются глобальными, то
есть доступными основной программе (программе или  модулю,  которые
используют  данный модуль).  Основная программа имеет доступ к этим
элементам, как если бы они  были  бы  объявлены  в  блоке,  который
включает главную программу.

интерфейсный раздел
 і
 і  ЪДДДДДДДДДї
 АДціinterfaсeГДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДц
    і         і і  ЪДДДДДДДДДДДїш ш і  ЪДДДДДДДДДДДДДДДДДДї  ш і
    АДДДДДДДДДЩ АДціпредложениеГЩ і ГДціраздел объявления ГДДґ і
                   і   uses    і  і і  і   констант       і  і і
                   АДДДДДДДДДДДЩ  і і  АДДДДДДДДДДДДДДДДДДЩ  і і
                                  і і  ЪДДДДДДДДДДДДДДДДДДї  і і
                                  і ГДціраздел объявления ГДДґ і
                                  і і  ітипов переменных  і  і і
                                  і і  АДДДДДДДДДДДДДДДДДДЩ  і і
                                  і і  ЪДДДДДДДДДДДДДДДДДДї  і і
                                  і ГДціраздел объявления ГДДґ і
                                  і і  іпеременных        і  і і
                                  і і  АДДДДДДДДДДДДДДДДДДЩ  і і
                                  і і  ЪДДДДДДДДДДДДДДДДДДї  і і
                                  і АДціраздел заголовков ГДДЩ і
                                  і    іпроцедур и функцийі    і
                                  і    АДДДДДДДДДДДДДДДДДДЩ    і
                                  АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

раздел заголовков
процедур и функций
  і        ЪДДДДДДДДДї           ЪДї
  АДДДДВДДцізаголовокГДДДДДДДДДДці;ГДВДДДДДДДДДДДДДДДДДДДДДДДц
       і   іпроцедурыі        ш  АДЩ і  ЪДДДДДДДДДї   ЪДї ш
       і   АДДДДДДДДДЩ        і      АДцідирективаГДДці;ГДЩ
       і  ЪДДДДДДДДДДДДДДДДДї і         і inline  і   АДЩ
       АДцізаголовок функцииГДЩ         АДДДДДДДДДЩ
          АДДДДДДДДДДДДДДДДДЩ


     Если процедура  или  функция  не  объявлена  как  inline,   то
интерфейсный   раздел   только  перечисляет  заголовки  процедур  и
функций. Тела процедур и функций находятся в разделе реализации.


                        Раздел реализации.

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


раздел реализации
 і
 і  ЪДДДДДДДДДї
 АДціimplemen-ГДВДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДВД>
    і tation  і і  ЪДДДДДДДДДДДї ш ш і  ЪДДДДДДДДДДДДДДДДДДї ш і                       ш і
    АДДДДДДДДДЩ АД>іпредложениеГДЩ і ГД>іраздел объявления ГДґ і
                   і   uses    і   і і  і    меток         і і і
                   АДДДДДДДДДДДЩ   і і  АДДДДДДДДДДДДДДДДДДЩ і і
                                   і і  ЪДДДДДДДДДДДДДДДДДДї і і
                                   і ГД>іраздел объявления ГДґ і
                                   і і  і    констант      і і і
                                   і і  АДДДДДДДДДДДДДДДДДДЩ і і
                                   і і  ЪДДДДДДДДДДДДДДДДДДї і і
                                   і ГД>іраздел объявления ГДґ і
                                   і і  ітипов переменных  і і і
                                   і і  АДДДДДДДДДДДДДДДДДДЩ і і
                                   і і  ЪДДДДДДДДДДДДДДДДДДї і і
                                   і ГД>іраздел объявления ГДґ і
                                   і і  іпеременных        і і і
                                   і і  АДДДДДДДДДДДДДДДДДДЩ і і
                                   і і  ЪДДДДДДДДДДДДДДДДДДї і і
                                   і АД>іраздел объявления ГДЩ і
                                   і    іпроцедур и функцийі   і
                                   і    АДДДДДДДДДДДДДДДДДДЩ   і
                                   АДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     По механизму   действия   объявление   процедур  и  функций  в
интерфейсном разделе аналогично forward объявлению,  хотя директива
forward  не  указывается.  Таким  образом,  эти процедуры и функции
могут  быть  определены  (и  к  ним  можно   обращаться   в   любой
последовательности) в разделе реализации.

     Примечание: Заголовки    процедур   и   функций   могут   быть
сдублированы  из  интерфейсного  раздела.  Необязательно   задавать
список формальных параметров,  но если вы сделали это,  то в случае
несоответствия  объявления  в  интерфейсном   разделе   и   разделе
реализации компилятор выдаст ошибку времени компиляции.


                       Раздел инициализации.

     Раздел инициализации является последним  разделом  модуля.  Он
может  состоять либо из зарезервированного слова end (в этом случае
модуль не содержит кода инициализации),  либо из операторной части,
которая должна выполняться для инициализации модуля.


                            ЪДДДї
раздел инициализации ДДДВДД>іendГДДДДДДДДДДДДДДДДДД>
                        і   АДДДЩ              ш
                        і  ЪДДДДДДДДДДДДДДДДДї і
                        АД>іоператорная частьГДЩ
                           АДДДДДДДДДДДДДДДДДЩ

     Разделы инициализации    модулей,     которые     используются
программой,  выполняются в том же порядке, в каком модули указаны в
предложении uses.


             Косвенные ссылки на используемые модули.

     В предложении  uses  в  программе или модуле указываются имена
только тех модулей,  которые явно используются  этим  модулем  (или
программой).
     Рассмотрим следующий пример:

               program Prog;
               uses Unit2;
               const a = b;
               begin
               end.

               unit Unit2;
               interfase
               uses Unit1;
               const b = c;
               implementation
               end.

               unit Unit1;
               interfase
               const c = 1;
               implementation
               const d = 2;
               end.

     В приведенном выше примере Unit2 явно зависит от Unit1, а Prog
явно  зависит  от Unit2.  Более того,  Prog неявно зависит от Unit1
(через Unit2),  хотя ни  один  из  идентификаторов,  объявленных  в
Unit1, недоступен Prog.
     Чтобы откомпилировать модуль,  Turbo Pascal должен  найти  все
модули,  от  которых  этот  модуль зависит (явно или неявно).  Так,
чтобы откомпилировать Prog,  компилятор должен найти Unit1 и Unit2,
в противном случае произойдет ошибка.
     Когда в интерфейсную часть модуля вносятся  изменения,  другие
модули,    использующие    этот    модуль,   должны   быть   заново
откомпилированы. Однако,  если изменения коснулись  только  раздела
реализации или раздела инициализации,  то другие модули,  в которых
используется этот модуль,  перекомпилировать не нужно. В предыдущем
примере,  если интерфейсная часть модуля Unit1 изменялась (например
С = 2),  то модуль  Unit2  нужно  перекомпилировать.  Изменение  же
раздела реализации (например, D=1) не требует перекомпиляции Unit2.
     При компиляции модуля в Turbo  Pascal  на  основе  контрольной
суммы  интерфейсного  раздела  вычисляется  номер версии модуля.  В
предыдущем примере при компиляции модуля Unit2  в откомпилированной
версии  модуля  Unit2  сохраняется  номер версии модуля Unit1.  При
компиляции   основной   программы   номер   версии   модуля   Unit1
сравнивается  с  номером версии,  сохраненным в модуле Unit2.  Если
номера версий не совпадают,  что  свидетельствует  об  изменении  в
интерфейсной  части  модуля  Unit1  со времени последней компиляции
модуля Unit2,  то компилятор,  в зависимости от режима  компиляции,
выдает сообщение об ошибке или перекомпилирует модуль Unit2.


                     Круговые ссылки модулей.

     Включение предложения  uses  в   разделе   реализации   модуля
позволяет  вам  скрыть внутренние элементы модуля,  так как модули,
используемые в разделе реализации, невидимы для пользователей этого
модуля.  Еще более важно, однако, что это также позволяет создавать
взаимно зависимые модули.
     Следующая программа   показывает,   как   два   модуля   могут
"использовать" друг друга. Основная программа, Circular, использует
модуль Display.  Display содержит одну программу,  WriteXY, которая
имеет три параметра: пару координат (X,Y) и текстовое сообщение для
вывода.  Если  точка  с координатами (X,Y) находится на экране,  то
WriteXY передвигает курсор в (X,Y) и выводит сообщение, в противном
случае она вызывает простую программу - обработчик ошибок.
     До сих пор нет ничего сложного - WriteXY  находится  в  Write.
Где   же   здесь   встречается   круговая   ссылка  модулей  и  как
программа-обработчик  ошибок  выведет  свое  сообщение  об  ошибке?
Использованием  WriteXY  снова.  Таким  образом,  имеется  WriteXY,
которая вызывает программу  обработчик  ошибок  ShowError,  которая
вызывает WriteXY, чтобы поместить сообщение об ошибке на экран.
     Если ваша  голова  закружилась,  посмотрите  на  исходный  код
примера, и вы увидите, что здесь нет ничего хитрого.
     Основная программа Circular,  очищает экран и трижды  вызывает
WriteXY :

          program Circular;
          {выводит на экран текст, используя WriteXY}
          uses
             Crt, Display;
          begin
             ClrScr;
             WriteXY(1, 1, 'Верхний левый угол экрана');
             WriteXY(100, 100, 'За пределами экрана');
             WriteXY(81 - Length('Возврат на экран'), 15,
                                 'Back to reality');
          end.


     Посмотрите на  координаты  (X,Y)  во  втором  вызове  WriteXY.
Трудно вывести текст в точке (100,100) на экран 80x25 строк. Далее,
давайте посмотрим,  как работает WriteXY.  Приведем исходный  текст
модуля Display, содержащий процедуру WriteXY. Если координаты (X,Y)
действительны, то он выводит на экран сообщение; в противном случае
WriteXY выводит сообщение об ошибке :

          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
                GoToXY(X, Y);
                Write(Message);
             end;
             else
                ShowError('Неправильные координаты WriteXY');
           end;
           end.

     Процедура ShowError,    вызываемая     процедурой     WriteXY,
объявлена в  модуле Еrror.  ShowError всегда выводит свое сообщение
об ошибке на 25 строке экрана :

               unit Error;
               {содержит простую программу-обработчик ошибок}
               interface
               procedure ShowError(ErrMsg: String);
               implementation
               uses
                  Display;
               procedure ShowError(ErrMsg: String);
               begin
                  WriteXy(1, 25, 'Error: ' + ErrMsg);
               end;
               end.

     Заметим, что  предложение uses в разделах реализаций Display и
Error ссылаются друг на друга.
     Эти два  модуля могут ссылаться друг на друга в своих разделах
реализации, потому что  Turbo  Pascal  может  компилировать  полные
разделы interface  для обоих модулей,  другими словами Turbo Pascal
допускает ссылку на частично откомпилированный модуль А  в  разделе
реализации  модуля  В,  пока  интерфейсные разделы модулей А и В не
зависят друг от друга (и это следует строгим правилам  Паскаля  для
порядка объявления).


                   Разделение других объявлений.

     Предположим, что Вы захотели изменить WriteXY и ShowError так,
чтобы ввести дополнительный параметр,  который задает прямоугольное
окно на экране :

    procedure WriteXY(SomeWindow: WindRec; X, Y: Integer;
                      Message: String);
    Procedure ShowError (SomeWindow: WindRec;
                         ErrMsg: String);

     Напомним, что эти процедуры  находятся  в  различных  модулях.
Даже если  вы  объявите  WindData  в  интерфейсе одного модуля,  то
нельзя законным путем сделать это объявление доступным в интерфейсе
другого  модуля.  Решением этой проблемы является создание третьего
модуля, содержащего только определение записи окна:

               unit WindData;
               interface
               type
                  WindRec = record
                     X1, Y1, X2, Y2: Integer;
                     ForeColor, BackColor: Byte;
                     Activ: Boolean;
                  end;
               implementation
               end.

     Вдобавок к  модификации   кода   WriteXY   и   ShowError   для
использования  нового  параметра,  интерфейсные  разделы  и  модуля
Display,  и модуля Error могут теперь "использовать" WindData.  Это
стало возможным потому, что модуль WindData не имеет зависимостей в
предложении uses,  а модуль Display и Error ссылаются друг на друга
только в соответствующих разделах реализации.


Яндекс цитирования