Управляющие структуры языка (операторы)

Содержание  |  Назад  |  Вперед

Простой и составной операторы

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

Оператор варианта CASE

Оператор цикла с предусловием WHILE

Оператор цикла с постусловием REPEAT ... UNTIL

Оператор цикла с параметром FOR

Процедуры BREAK, CONTINUE, EXIT и HALT

 

Простой и составной операторы

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

Два последовательных оператора обязательно должны разделяться точкой с запятой “;”.

Примеры простых операторов:

a := 10; b := a*5; Write( a, b );

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

Составной оператор – это последовательность операторов, перед которой стоит слово BEGIN, а после – END. Слова BEGIN и END часто именую операторными скобками.

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

        BEGIN
          a := 10;
          b :+ a*5;
          Write( a, b )
        END;

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

ВАЖНО: Составной оператор применяется в тех случаях, когда синтаксис языка Паскаль допускает использование только одного оператора, в то время как алгоритм требует задания некоторой последовательности действий. В Паскале все управляющие структуры (операторы) не различают простой и составной оператор: там где стоит простой оператор, можно поставить и составной.

 

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

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

Синтаксис оператора IF:

IF Условие THEN Оператор1 ELSE Оператор2;

или

IF Условие THEN Оператор;

Условие может быть представлено логической константой (FALSE – ложь, TRUE - истина), переменной логического типа (Boolean) или логическим выражением.

Если условие истинно, то выполняется оператор (простой или составной), следующий за словом THEN, в противном случае, когда условие ложно, будет выполняться оператор, следующий за словом ELSE. Альтернативная ветвь ELSE может отсутствовать, если в ней нет необходимости. В таком “усеченном” варианте, в случае, если условие оказывается ложным, ничего не происходит и выполняется оператор следующий за условным оператором IF.

Пример 1.

Пусть необходимо составить программу, вычисляющую значение функции:

VAR
  x, y : real;
BEGIN
  Write(‘Введите значение аргумента: ’); ReadLn(x);
  IF x>0 THEN y := x
         ELSE y := 0;
  Write(‘Значение функции y = ’, y)
END.

Условные операторы могут быть вложенными друг в друга:

IF Условие THEN if ПодУсловие then ... else ...
                  ELSE ...;

Обратите внимание на отсутствие точки с запятой между ключевыми словами.

При вложениях условных операторов самое главное – не запутаться в вариантах сочетаний условий (отчасти этому может помочь ступенчатая форма записи операторов). Всегда действует правило: альтернатива ELSE считается принадлежащей ближайшему условному оператору IF, не имеющему ветви ELSE. Например:

IF Условие1 THEN if Условие2 then Оператор_А
            ELSE Оператор_Б;

По записи может сложиться впечатление, что Оператор_Б будет выполняться только при “невыполнении” Условия1. Но на самом деле он будет отнесен к Условию2 и выполнится только при выполнении Условия1 и невыполнении Условия2! Если необходимо, чтобы Оператор_Б выполнялся именно при невыполнении Условия1, то единственный выход таков: заключить вложенный (усеченный) оператор IF в операторные скобки begin…end:

IF Условие1 THEN begin
                   if Условие2 then Оператор_А
                 end
            ELSE Оператор_Б;

В условии оператора IF может стоять достаточно сложное логическое выражение. О правилах построения логических выражений см. раздел “Логические выражения”.

 

Оператор варианта CASE

Оператор варианта необходим в тех случаях, когда в зависимости от значения какой-либо переменной нужно выполнить те или иные операторы (простые или составные). Если вариантов всего два, то можно обойтись и оператором IF. Но если их, например, десять? В этом случае оптимален оператор варианта CASE.

Синтаксис оператора CASE:

CASE УправляющаяПеременнаяИлиВыражение OF
    НаборЗначений1 : Оператор1;
    НаборЗначений2 : Оператор2;
    НаборЗначений3 : Оператор3;
            . . .
    НаборЗначенийN : ОператорN
    ELSE АльтернативныйОператор
END;

Между служебными словами CASE и OF должна стоять переменная или выражение (оно вычисляется при исполнении оператора CASE) целочисленного или любого порядкового типа. Набор значенийэто конкретные значения управляющей переменной или выражения, при которых необходимо выполнить соответствующий оператор, игнорируя остальные варианты. Если в наборе несколько значений, то они разделяются между собой запятой.. Можно указывать диапазоны значений, например, 0..9 – все значения от нуля до девяти. Наборы значений и диапазоны можно комбинировать. Между набором значений и соответствующим ему оператором обязательно ставится символ “:”. Значения в каждом наборе должны быть уникальными, т.е. они могут появиться только в одном варианте. Пересечение наборов значений для разных вариантов является ошибкой, и она будет замечена компилятором.

Оператор (Оператор1, Оператор2, …) в конкретном варианте может быть как простым, так и составным.

Пример 1.

PROGRAM Example_CASE_1;
VAR A : integer;
BEGIN
    Write(‘Введите оценку: ‘); Read(A);
    CASE A OF
        2 : Write(‘неудовлетворительно’);
        3 : Write(‘удовлетворительно’);
        4 : Write(‘хорошо’);
        5 : Write(‘отлично’)
        ELSE Write(‘Ошибка!’)
    END;
END.

Здесь в зависимости от значения переменной А на экран выводится наименование оценки. Наличие варианта ELSE обеспечивает вывод сообщения об ошибке в случае, когда введено число вне интервала 2..5.

Пример 2.

PROGRAM Example_CASE_2;
VAR Hour : integer;
BEGIN
    Read( Hour );
    CASE Hour OF
        0, 24 : Write(‘Полночь’);
        1..4 : Write(‘Ночь’);
        5..7 : Write(‘Раннее утро’);
        8..11 : Write(‘Утро’);
        12 : Write(‘Полдень’);
        13..17 : Write(‘День’);
        18..23 : Write(‘Вечер’)
        ELSE Write(‘Введено число вне диапазона 0..24!’)
    END;
END.

 

Оператор цикла с предусловием WHILE

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

Синтаксис оператора WHILE:

WHILE Условие DO Оператор;

Конструкция WHILE…DO переводится как “пока…делать”. Оператор (простой или составной), стоящий после служебного слова DO и называемый телом цикла, будет выполнятся циклически, пока значение “Условия” равно TRUE (истина). Само условие цикла может быть логической константой, переменной или логическим выражением.

Условие выполнения тела цикла WHILE проверяется до начала каждой итерации. Поэтому если условие сразу не выполняется, то тело цикла игнорируется и будет выполнятся оператор, стоящий сразу за телом цикла.

Оператором в теле цикла может быть другой циклический оператор, т.е. циклы могут быть вложенными.

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

Пример цикла WHILE: Вычисление факториала 10! = 1·2·3·4·5·6·7·8·9·10

VAR
  Factorial, N : Integer;
BEGIN
  Factorial := 1; {стартовое значение факториала =0! }
  N := 1;         {стартовое значение для условия цикла }
  WHILE N<=10 DO                {заголовок цикла, условие }
   begin                        {начало тела цикла }
     Factorial := Factorial*N; {вычисление факториала N! }
     N := N + 1                 {N должно меняться в цикле}
   end;                         {конец тела цикла }
  WriteLn(’10!= ’,Factorial);  {вывод результата расчета }
END.

Обратите внимание на присваивание N:=1 пред циклом. Без него значение N может быть любым, и условие может оказаться некорректным, не говоря уже о самом значении факториала. Значение N меняется внутри цикла. При этом гораздо безопаснее так писать тело цикла, чтобы оператор, влияющий на условие, был бы последним. Это гарантирует от нежелательных переборов. Если, скажем, в рассмотренном выше примере, поставить строку N:=N+1; перед вычислением факториала, то результатом программы будет значение 11!. Исправить оплошность можно, заменив стартовое значение N на 0, а условие – на N<10. Но от этого программа вряд ли станет нагляднее.

 

Оператор цикла с постусловием REPEAT…UNTIL

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

Синтаксис оператора REPEAT…UNTIL:

REPEAT
  Оператор1;
  Оператор2;
  ···
  ОператорN;
UNTIL Условие;

Операторы (Оператор1, Оператор2, … ОператорN), образующие тело цикла, будут выполнятся циклически, до тех пор пока значение “Условия” не станет равно TRUE (истина). Иными словами, в цикле REPEAT…UNTIL условием продолжения итераций является невыполнение “Условия” (его значение FASLE – ложь).

Условие цикла может быть логической константой, переменной или логическим выражением.

Оператор REPEAT…UNTIL имеет две части: начальную (слово REPEAT) и завершающую (слово UNTIL), которые охватывают группу операторов, составляющих тело цикла. Поэтому необходимости в использовании составного оператора для построения тела цикла из нескольких простых операторов не возникает.

Принципиальное отличие оператора REPEAT…UNTIL от оператора WHILE в том, что проверка условия производится не перед началом выполнения тела цикла, а после его выполнения, когда решается вопрос, повторить ли еще раз действия. Поэтому тело цикла всегда выполняется по крайней мере один раз.

Пример 1. Проверка ввода

VAR
  N : Integer;
BEGIN
  . . .
  REPEAT
    Write(‘Введите целое число от 0 до 10: ’);
    ReadLn(N);
  UNTIL (N>=0) and (N<=10);
  . . .
END.

В этом примере программа будет запрашивать ввод числа до тех пор, пока пользователь не введет “правильное” число.

Пример 2. “Вечный цикл”

REPEAT UNTIL False;

Этот цикл пустой и никогда не прекращающийся. Он хорош только в том случае, когда нужно заблокировать программу, и, возможно весь компьютер. (Но если отбросить шутки, то можно и его пристроить в дело. Обычно так организуют программы с повторяющимися действиями: вначале программы ставят REPEAT, а в конце – UNTIL False. А прервать цикл можно специальными операторами EXIT и HALT). Это имеет смысл, если условий завершения программы много или они очень сложны.)

 

Оператор цикла с параметром FOR

Оператор цикла с параметром вводится для организации “строгих” циклов, которые должны быть проделаны заданное число раз. Кроме того, циклы с параметром позволяют организовать автоматическое изменение значения некоторой переменной в определенном диапазоне.

Синтаксис оператора FOR:

FOR ПараметрЦикла := МладшееЗначение TO СтаршееЗначение DO Оператор;

или

FOR ПараметрЦикла := СтаршееЗначение DOWNTO МладшееЗначение DO Оператор;

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

Изменение параметра цикла может быть как возрастающим, так и убывающим. В первом случае МладшееЗначение должно быть больше чем Старшее, а во втором – наоборот.

Примеры оформления циклов с параметром.

VAR i : integer;
BEGIN
  FOR i := 1 TO 10 DO Write(i:5);
  FOR i := 5 DOWNTO 0 DO Write(i:5)
END.

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

CONST n = 10;
      m = 3;
VAR i,
    k : integer;
BEGIN
  k := 1;
  FOR i := k TO n DO Write(i:5);
  FOR i := (m+2) DOWNTO 0 DO Write(i:5)
END.

Выполнение цикла начинается с присваивания параметру стартового значения. Затем следует проверка, не превосходит ли параметр конечное значение (случай с TO) или не является ли он меньше конечного значения (случай с DOWNTO). Если результат проверки утвердительный, то цикл считается завершенным. В противном случае выполняется тело цикла (оператор, следующий за словом DO), и после этого параметр цикла меняет свое значение на следующее. Далее снова производится проверка значения параметра цикла, т.е. алгоритм повторяется.

Запрещается изменять параметр цикла и его старшее и младшее значения внутри тела цикла. Кроме того, параметр цикла не может участвовать в построении диапазонов этого же цикла. Компилятор таких “незаконных” действий не замечает, но программа, содержащая цикл с заголовком типа

FOR i := i-5 TO i+5 DO ... ;

не заслуживает никакого доверия, даже если запускается!

Операторы FOR могут быть вложенными друг в друга, например

VAR
  i,j : integer;
BEGIN
  WriteLn(‘Таблица умножения’);
  FOR i := 1 TO 10 DO begin
     FOR j := 1 TO 10 DO Write((i*j):5);
    WriteLn;
  end;
END.

 

Процедуры BREAK, CONTINUE, EXIT и HALT

Процедура BREAK применяется для досрочного прекращения циклов WHILE, REPEAT…UNTIL и FOR.

Пример: Определение номера первого нулевого элемента в массиве А

VAR
  i, num : Integer;
  A : array[1..10] of Integer;
BEGIN
  . . . { Ввод элементов массива А }
  num := 0;
  FOR i:=1 TO 10 DO { Цикл для i от 1 до 10 }
   IF A[i]=0 THEN begin { если найден нулевой элемент }
                    num := i; { запоминаем его номер }
                    BREAK      { прекращаем цикл }
                  end;
  IF num <> 0 THEN WriteLn(num)
              ELSE WriteLn(‘Нулевых элементов нет’);
END.

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

Пример: Определение наибольшего общего делителя (НОД) двух чисел

VAR
  CommDiv,        { кандидат в НОД }
  num1,           { первое число }
  num2 : Integer; { второе число }
BEGIN
  Write(‘Введите первое число: ’); ReadLn(num1);
  Write(‘Введите второе число: ’); ReadLn(num2);
  FOR CommDiv := num1 DOWNTO 1 DO begin
    IF (num2 mod CommDiv)<> 0 THEN CONTINUE;
    IF (num1 mod CommDiv) = 0 THEN begin
       WriteLn(‘Наибольший общий делитель: ’, CommDiv);
       BREAK
    end {if}
end {for}
END.

В примере применен цикл FOR, в котором по убывающий перебираются возможные кандидаты в наибольший общий делитель. Критерий делимости – равенство нулю остатка от деления (операция mod). Если кандидат (значение переменной CoomDiv) не является делителем числа num2, по команде CONTINUE начинается следующий проход цикла, а операторы, оставшиеся в теле цикла, не выполняются. Если число (CommDiv) оказывается делителем числа num2 и num1, что проверяется вторым оператором IF тела цикла, значит, оно – общий делитель. А поскольку перебор идет от больших к меньшим значениям, первый найденный общий делитель – наибольший. Выводим его на печать и прерываем цикл командой BREAK.

EXIT

Процедура EXIT завершает работу своего программного блока. Если EXIT вызывается внутри процедуры или функции, то их работа завершается. Если EXIT вызывается в основном блоке программы, то это приводит к ее завершению.

HALT

Процедура HALT, или более полно HALT(n),   завершает работу программы с кодом завершения n. Этот код впоследствии может быть проанализирован, в частности командой IF ERRORLEVEL в среде MS-DOS. Значение ERRORLEVEL после остановки программы будет равно значению n. Вызов процедуры HALT без параметра эквивалентен вызову HALT(0).

На основе процедуры HALT можно легко построить программу, например ASK.PAS, для организации диалога в BAT-файлах MS-DOS.

Например:

PROGRAM ASK;
VAR i : Word;
BEGIN
  ReadLn(i);
  HALT(i)
END.

После компиляции получаем файл – AKS.EXE

Пример BAT-файла:

@ECHO OFF
CLS
ECHO Сейчас вы можете:

ECHO 0 - Завершить работу
ECHO 1 – Запустить Norton Commander
ECHO 2 – Отформатировать жесткий диск
ECHO Ваш выбор ?
ask.exe

IF ERRORLEVEL 0 GOTO end
IF ERRORLEVEL 1 GOTO startNC
IF ERRORLEVEL 2 GOTO formatHDD
GOTO end
:startNC
   c:\nc\nc
:formatHDD
   format C: /s
:end

 

Содержание |  Назад  |  Вперед