



                          ГЛАВА 7

                         Операторы

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

 Оператор -------------------------------------------------->
           ! -------   ---  ^ !    --------------------   ^
           ->!метка!->( : )-! !--->! простой оператор !---!
             -------   ---    !    --------------------   !
                              !    ---------------------  !
                              ---->!    структурный    !---
                                   !      оператор     !
                                   ---------------------

                     Простые операторы

     Простым оператором является такой оператор, который  не
содержит в себе других операторов.

                             -------------------------
 Простой оператор ---------->! оператор присваивания !----->
                      !      -------------------------    ^
                      !      -------------------------    !
                      !----->!   оператор процедуры  !----!
                      !      -------------------------    !
                      !      -------------------------    !
                      ------>!   оператор перехода   !-----
                             -------------------------

                   Оператор присваивания

     Оператор присваивания заменяет  текущее  значение пере-
менной новым значением, которое определяется выражением, или

                                - 2 -


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

               ------------------------        ----
 Оператор  --->! ссылка на переменную !------>( := )--
присваивания ! ------------------------     ^  ----  !
             ! -------------------------    !        !
             ->! идентификатор функции !-----        !
               -------------------------  ------------
                                          !  -------------
                                          -->! выражение !->
                                             -------------

     Выражение должно быть совместимо по  присваиванию с ти-
пом переменной или типом значения, возвращаемого  функцией в
качестве результата (см. раздел "Совместимость типов" в Гла-
ве 3 "Типы").
     Приведем некоторые примеры операторов присваивания:

  X := Y + Z
  Done := (I>=1) and (I<100);
  Huel := [blue,Succ(C)];
  I := Sqr(J) - I*K;

                     Операторы процедуры

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


                                - 3 -


              ---------------------------
 Оператор --->! идентификатор процедуры !------------------>
 процедуры    --------------------------- !            ^
                                          ! ---------- !
                                          ! ! список ! !
                                          ! ! факти- ! !
                                          ->! ческих !--
                                            ! пара-  !
                                            ! метров !
                                            ----------

     Приведем некоторые примеры операторов процедур:

  PrintHeaing;
  Transpose(A,N,M);
  Fin(Name,Address);


                     Операторы перехода

     Оператор перехода вызывает передачу управления операто-
ру, которому предшествует метка, указанная в данном операто-
ре  перехода.  Синтаксическая схема оператора перехода имеет
следующий вид:

                          -------        ---------
 Оператор перехода ----->( gоtо  )------>! метка !------>
                          -------        ---------

     При использовании оператора перехода должны соблюдаться
следующие правила:
     1.  Метка, которая  указывается  в  операторе перехода,
         должна находиться в том же блоке или  модуле, что и
         сам оператор перехода. Другими словами, не допуска-
         ются переходы из процедуры или функции  или  внутрь
         нее.
     2.  Переход извне  внутрь  структурного  оператора  (то
         есть переход на более глубокий уровень вложенности)

                                - 4 -


         может вызвать непредсказуемые эффекты, хотя  компи-
         лятор не выдает сообщения об ошибке.

                   Структурные операторы

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

                             ----------------------
 Структурный оператор ------>! составной оператор !-------->
                        !    ----------------------      ^
                        !    ----------------------      !
                        !--->!  условный оператор !----->!
                        !    ----------------------      !
                        !   ------------------------     !
                        !-->!    оператор цикла    !---->!
                        !   ------------------------     !
                        !   -------------------------    !
                        --->! оператор над записями !-----
                            -------------------------

                    Составные операторы

     Составные операторы задают  порядок выполнения операто-
ров, являющихся их элементами.  Они должны выполняться в том
порядке, в котором они записаны. Составные операторы обраба-
тываются,  как  один  оператор, что имеет решающее  значение
там, где синтаксис  Паскаля допускает  использование  только
одного оператора. Операторы заключаются в ограничители begin
и end, и отделяются друг от друга точкой с запятой.

                        -------    ------------    -----
 Составной оператор -->( begin )-->! оператор !-->( end )-->
                     ^  -------    ------------ !  -----
                     !                 ---      !
                     -----------------( ; )<-----
                                       ---

                                - 5 -


     Приведем пример составного оператора:

  begin
    Z := X;
    X := Y;
    Y := Z;
  end;

                     Условные операторы

     Условные операторы  позволяют  выбрать  для  выполнения
один из составных операторов (или не выбрать ни одного).

                                 -----------------
Условный оператор -------------->! оператор if   !-------->
                    !            -----------------    ^
                    !   ----------------------        !
                    --->!   оператор case    !---------
                        ----------------------

                        Оператор if

     Синтаксис оператора if можно представить  следующим об-
разом:

              ----   -----------   ------   ----------
Оператор if->( if )->!выражение!->( then )->!оператор!-----
              ----   -----------   ------   ----------  ! !
                    ------------------------------------- !
                    !   ------     --------------         !
                    -->( else )--->!  оператор  !----------->
                        ------     --------------

     В выражении должен  получаться результат, имеющий стан-
дартный  булевский тип.  Если результатом выражения является
истинное значение (Тrue), то выполняется оператор, следующий

                                - 6 -


за ключевым словом then.
     Если  результатом  выражения  является значение False и
присутствует ключевое слово else,  то  выполнятся  оператор,
следующий за ключевым словом else. Если ключевое слово  else
отсутствует, то никакой оператор не выполняется.
     Синтаксическая неоднозначность, возникающая в конструк-
ции:

  if e1 then e2 else e3

разрешается путем следующей интерпретации этой конструкции:

 if e1 then
 begin
   if e2 then
      s1
   else
      s2
 end

     В  общем случае ключевое слово else связывается с  бли-
жайшим ключевым словом if, которое еще не связано с ключевым
словом else.
     Приведем два примера оператора if:

  if X < 1.5 then
    Z := X+Y
  else
    Z := 1.5;

   if P1 <> nil then
     P1 := P1^.father;

                  Оператор варианта (case)

     Оператор варианта (casе) состоит из выражения (переклю-
чателя) и списка операторов, каждому из которых предшествует
одна или более констант (они называются  константами выбора)

                                - 7 -


или ключевое слово else. Переключатель должен иметь перечис-
лимый тип и перечислимые значения верхней и  нижней  границы
этого типа должны лежать в диапазоне от -32768 до 32767. Та-
ким образом, строковый тип и длинный целый тип являются  не-
допустимыми типами переключателя. Все константы выбора дожны
быть уникальными и иметь перечислимый тип, совместимый с ти-
пом переключателя.

               ------    -----------   ----    --------
 Оператор --->( casе )-->!выражение!->( оf )---! casе !----
 варианта      ------    -----------   ----  ^ -------- ! !
                                             !   ---    ! !
                                             ---( ; )---- !
                                                 ---      !
        ---------------------------------------------------
        !                                          -----
        ----------------------------------------->( еnd )-->
         !  --------------    ^   !    ---    ^    -----
         -->! ветвь else !----!   --->( ; )---!
            --------------             ---

                     ----------------------->
                     !                      !
       ------------- !  ----   -----------  !  ---
casе ->! константа !-->( .. )->!константа!--->( : )---
     ^ -------------    ----   -----------  !  ---   !
     !                  ----                ! --------
     ------------------( ,  )<--------------- ! ------------
                        ----                  ->! оператор !->
                                                ------------

                   ------    ------------
ветвь else ------>( else )-->! оператор !-------------->
                   ------    ------------

     Оператор варианта приводит к  выполнению оператора, ко-
торому предшествует константа выбора, равная значению перек-
лючателя или диапазону выбора, в котором  находится значение

                                - 8 -


переключателя. Если такой константы выбора или такого диапа-
зона выбора не существует и присутствует ветвь  else, то вы-
полнятся оператор, следующий за ключевым словом  else.  Если
же ветвь else отсутствует, то никакой оператор не выполняет-
ся.
     Приведем некоторые примеры оператора варианта:

  case Operator of
    plus:   X := X+Y;
    minus:  X := X-Y;
    times:  X := X*Y;
  end;

                      Оператор цикла

     Оператор цикла задает повторное выполнение определенных
операторов.
                             -------------------
 Оператор цикла ------------>! оператор repeat !---------->
                        !    -------------------    ^
                        !    -------------------    !
                        !--->!  оператор while !----!
                        !    -------------------    !
                        !    -------------------    !
                        ---->!   оператор for  !-----
                             -------------------

     Если число повторений заранее  известно, то  подходящей
конструкций является оператор for. В противном случае следу-
ет использовать операторы while или repeat.

          Оператор цикла с пост-условием (repeat)

     В операторе цикла с пост-условием (начинающимся со сло-
ва repeat) выражение, которое управляет повторным выполнени-
ем последовательности операторов содержится внутри оператора
repeat.


                                - 9 -


           --------    ----------    -------   ----------
Оператор->( repeat )---!оператор!-->( until )->!оператор!-->
 цикла с   --------  ^ ---------- !  -------   ----------
пост-условием        !     ---    !
                     -----( ; )<---
                           ---

     Результатом выражения должен быть результат  булевского
типа. Операторы, заключенные между ключевыми словами  repeat
и  until,  выполняются  последовательно до тех пор, пока ре-
зультат выражения не примет  значение  Тrue.  Последователь-
ность операторов выполнится по крайней мере  один  раз, пос-
кольку вычисление выражения производится после  каждого  вы-
полнения последовательности операторов.
     Приведем примеры оператора цикла с пост-условием:

  repeat
    K := I mod J;
    I := J;
    J := K;
  until J = 0;

 repeat
   Write('Введите значение (0..9):');
   Readln(I);
 until (I >= 0) and (I <= 9);


           Операторы цикла с пред-условием (while)

     Оператор цикла с  пред-условием  (начинающийся со слова
while) содержит в себе выражение, которое управляет  повтор-
ным выполнением оператора (который может быть составным опе-
ратором).

                 -----    -----------   ----   ----------
Оператор цикла->(while)-->!выражение!->( dо )->!оператор!--->
с пред-условием  -----    -----------   ----   ----------

                                - 10 -



     Выражение, с помощью которого осуществляется управление
повторением  оператора, должно иметь булевский тип. Вычисле-
ние его производится до того, как внутренний оператор  будет
выполнен.  Внутренний  оператор  выполнятся  повторно до тех
пор, пока выражение принимает значение Тruе. Если  выражение
с  самого  начала принимает значение False, то оператор, со-
держащийся внутри оператора цикла с пред-условием, не выпол-
няется.
     Примерами оператора цикла в  пред-условием  могут  слу-
жить:

  while Data[I] <> X do I := I + 1;

  While I > 0 do
  begin
    if Odd(I) then Z := Z * X;
    I := I div 2;
    X := Sqr(X);
  end;

  while not Eof(InFile) do
  begin
    Readln(InFile,Line);
    Process(Line);
  end;

              Операторы цикла с параметром (for)

     Операторы цикла с  параметром  (которые  начинаются  со
слова for) вызывает  повторяющееся выполнение оператора (ко-
торый может быть  составным оператором) пока управляющей пе-
ременной  присваивается возрастающая последовательность зна-
чений.

                                - 11 -


                 -----   ------------------------   ----
Оператор цикла->( for )->!управляющая переменная!->( := )--
с параметром     -----   ------------------------   ----  !
                        --------------------------        !
        ----------------!    начальное значение  !<--------
        !               --------------------------
        !    ----
        !-->( tо )------
        !    ----      !  -------------------   ----
        !              !->!конечное значение!->( dо )----
        !  --------    !  -------------------   ----    !
        ->( downto )----      ---------------------------
           --------           !  -------------------
                              -->!     оператор    !------->
                                 -------------------

                           ----------------------------
 Управляющая переменная -->! идентификатор переменной !--->
                           ----------------------------

                           -------------
 Начальное значение ------>! выражение !------------------>
                           -------------

                           -------------
 Конечное значение ------->! выражение !------------------>
                           -------------

     В качестве управляющей переменной должен использоваться
идентификатор переменой (без какого-либо квалификатора), ко-
торый обозначает  переменную, объявленную локальной в блоке,
в котором содержится  оператор  for.  Управляющая переменная
должна иметь перечислимый тип. Начальное и конечное значения
должны иметь тип, совместимый по присваиванию с перечислимым
типом.
     Когда начинает выполняться оператор  for,  начальное  и
конечное значения определяются один раз, и эти значения сох-
раняются на протяжении всего выполнения оператора for.
     Оператор, который  содержится в теле оператора for, вы-

                                - 12 -


полняется один раз для  каждого  значения в  диапазоне между
начальным и конечным значением. Управляющая переменная всег-
да инициализируется начальным значением. Когда работает опе-
ратор for, значение управляющей переменной увеличивается при
каждом повторении на единицу. Если начальное значение превы-
шает конечное значение, то содержащийся в теле оператора for
оператор не выполнятся. Когда в операторе цикла используется
ключевое слово downto, значение управляющей переменной
уменьшается при каждом повторении на единицу. Если начальное
значение в таком операторе меньше, чем конечное значение, то
содержащийся в теле оператора цикла оператор не выполнятся.
     Если оператор, содержащийся в теле оператора for, изме-
няет значение управляющей переменной, то  это является ошиб-
кой.  После  выполнения  оператора  for значение управляющей
переменной становится неопределенным, если только выполнение
оператора for не было прервано с помощью оператора перехода.
     Если принять во внимание эти ограничения, то оператор

  for V := Expr1 to Expr2 do Body;

эквивалентен оператору:

  begin
    Temp1 := Expr1;
    Temp2 := Expr2;
  if Temp1 <= Temp2 then
  begin
    V := Temp1;
    Body;
    while V <> Temp2 do
    begin
      V := Succ(V);
      Body;
    end;
  end;
 end;

и оператор цикла


                                - 13 -


 for V := Expr1 downto Exp2 do Body;

эквивалентен операторам:

 begin
   Temp1 := Expr1;
   Temp2 := Expr2;
   if Temp1 >= Temp2 then
   begin
     V := Temp1;
     Body;
     while V <> Temp2 o
     begin
       V := Pred(V);
       Body;
     end;
   end;
  end;

где Temp1 и Temp2 -  вспомогательные переменные, тип которых
совпадает с основным  типом переменной V и которые не встре-
чаются в другом месте программы.
     Приведем примеры оператора цикла с параметром:

  for I := 2 to 63 do
    if Data[I] > Max then Max := Data[I]

  for I := 1 to 10 do
    for J := 1 to 10 do
    begin
      X := 0;
      for K := 1 to 10 do
        X := X + Mat1[I,K]*Mat2[K,J];
      Mat[I,J] := X;
    end;

  for C := red to blue do Check(C);


                                - 14 -


                  Операторы присоединения (with)

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

                 ------    ----------------------    ----
   Оператор --->( with )-->! ссылка на пере-    !-->( dо )--
 присоединения   ------  ^ ! менную типа запись ! !  ----  !
                         ! ---------------------- !        !
                         !          ---           !        !
                         ----------( , )<----------        !
                                    ---                    !
                             -------------------------------
                             !    --------------------
                             ---->!     оператор     !--->
                                  --------------------

                             ------------------------
 Ссылка на переменную ------>! ссылка на переменную !----->
     типа запись             ------------------------

     Приведем пример оператора with:

   with Date do
     if month = 12 then
     begin
       month := 1;
       year := year + 1
     end else
       month := month + 1;

     Это эквивалентно следующему:

   if Date.month = 12 then
   begin

                                - 15 -


     Date.month := 1;
     Date.year := Date.year + 1
   end else
     Date.month := Date.month + 1;

     В операторе присоединения сначала производится проверка
каждой ссылки на переменную, а именно: можно ли ее интерпре-
тировать, как поле записи. Если это так, то она всегда инте-
рпретируется именно таким образом, даже если имеется доступ
к переменной с тем же именем.
     Допустим объявлены следующие переменные:

  type
    Point = record
              x,y: integer;
            end;
    var
      x: Point;
      y: Integer;

     В этом случае и к x, и к y можно обращаться, как к пе-
ременной или как к полю записи. В операторе:

  with x do
  begin
    x := 10;
    y := 25;
  end;

x между ключевыми словами with и dо относится к переменной
типа указатель, а в составном операторе x и y ссылаются на
x.x и y.y.
     Оператор

  with V1,V2,...Vn do s;

эквивалентен операторам:


                                - 16 -


 with V1 do
   with V2 do
    ...
      with Vn do
        S;

     В обоих случаях, если Vn является полем и  v1, и v2, то
она интерпретируется как v2.Vn, а не как v1.Vn.
     Если выборка переменной типа запись связана  с индекси-
рованием массива или вычислением указателя, то  эти действия
производятся до того, как будет выполняться составной опера-
тор.



