    2. УПРАВЛЯЮЩИЕ КОНСТРУКЦИИ и УТВЕРЖДЕНИЯ  19


    2. Процесс выполнения программы. Управляющие конструкции и утверждения 

    Мы уже говорили, что программа — это формальное описание 
последовательности вызовов предписаний, и объясняли, что происходит при 
выполнении программы. До сих пор, однако, мы не уточняли, кто и как выполняет 
программу, т. е. переводит это формальное описание в конкретную 
последовательность вызовов. В программировании обычно считается, что эту 
работу выполняет некоторое автоматическое устройство — машина. Мы будем 
называть это 

    Рис.   2.1.   Процесс   выполнения   программы 

устройство Универсальным  Выполиителем, или  ЭПВМ - Электронно-Программной 
Выполняющей Машиной (рис. 2.1). 
    Для того чтобы программу могло выполнить автоматическое устройство, 
программа должна подчиняться строгим правилам, записываться на некотором 
понятном ЭПВМ формальном языке. Этот язык принято называть языком 
программирования. Разные ЭПВМ могут выполнять программы, вообще говоря, на 
различных языках. Таким образом, использованный нами язык программирования — 
лишь один из многих. В последних главах книги мы познакомимся с двумя другими 
языками (двумя другими Универсальными Выполнителями). Всего же в мире 
существуют тысячи языков программирования и продолжают появляться все новые. 

    20 ГЛ. 1  НАЧАЛА ПРОГРАММИРОВАНИЯ 

    Программы можно выполнять и без автоматического Универсального 
Выполнителя, Например, человек может читать текст программы и нажимать на 
соответствующие кнопки на соответствующих исполнителях. В дальнейшем нас 
будет интересовать, не кто выполняет наши программы, а существо дела — как 
записать программу и что произойдет при ее выполнении. Однако удобно 
объяснять смысл тех или иных форм записи программ, описывая поведение 
Универсального Выполнителя при их выполнении. 
    Например, выполнение строки «СК. добавить <5> в стек» в программе 
«вычисление» можно описать так: Универсальный Выполнитель (УВ), дойдя до 
этой строки в тексте программы, анализирует систему предписаний исполнителя 
СК, т. е. ищет строку, которая вне скобок < и > в точности совпадает со 
строкой программы. Обнаружна такую строку, т. е. строку «добавить <вх: 
число> в стек» УВ устанавливает входной объект «число» в состояние 5 и 
«нажимает нужную кнопку» — обращается с соответствующим предписанием к 
Стековому калькулятору. 
    В соответствии с принятой в программировании терминологией будем называть 
число 5 в тексте программы фактическим параметром, объект «число» в системе 
предписаний — формальным параметром, а факт установки объекта «число» в 
состояние 6 — установкой соответствия формальных и фактических параметров. 

    Управляющие конструкции. 

   Приведенные в разд. 1 программы были весьма примитивными: каждая из 
них описывала фиксированную последовательность вызовов предписаний, 
совершенно на зависящую от состояния исполнителя, выполняющего эти 
предписания. Программа может, однако, описывать и более сложные 
последовательности, зависящие от тех или иных условий 
    Рассмотрим пример: 

   программа осторожный шаг 
   .  дано        : | Путник где-то в квадранте 
   . получить: 
   . -----------------
   .   если Путник.впереди свободно 
       .   то 
    .   .      Путник.сделать шаг 
    .    конец если 
   конец программы 

    Эта программа содержит новую форму записи — управляющую конструкцию 
   если (условие) 
   .  то     
   .     (действия) 
   конец если 

    2. УПРАВЛЯЮЩИЕ КОНСТРУКЦИИ И УТВЕРЖДЕНИЯ  21 

    Конструкция называется управляющей, так как сама по себе она 
не приводит ни к каким вызовам предписаний, а лишь управляет порядком 
таких вызовов. Хотя смысл конструкции если — то— конец если интуитивно ясен, 
поясним его, изобразив схему работы Универсального Выполнителя при выполнении 
этой конструкции (рис. 2.2). (Справа на рис. 2.2 изображена краткая форма, 
которой мы будем пользоваться в дальнейшем.) 
    Таким образом, при выполнении программы «осторожный шаг» Универсальный 
Выполнитель сначала анализирует условие между словами если и то, т. е. 
обдащается к Путнику с предписанием 


    Рис.   2.2 

«впереди свободно». Так как это — предписание, вырабатывающее значение 
типа да/нет, то Путник отвечает либо да, либо нет. Если условие выполнено 
(Путник ответил да), то Универсальный Выполнитель выполняет строки между то и 
конец если (т. е. командует Путнику «сделать шаг»). В противном случае текст 
между то и конец если пропускается. 
    Строго говоря, программа «осторожный шаг» описывает не одну а две 
последовательности вызовов предписаний. Конкретная последовательность 
определяется лишь при выполнении этой программы. Таким образом, фразу 
«программа — формальное описание последовательности вызовов предписаний», 
следует понимать именно в таком динамическом смысле. В рамках метафоры 
Универсаль-ного Выполнителя мы можем понимать программу как программу его 
действий — формальный текст, полностью описывающий поведение Универсального 
Выполнителя е учетом всех тех условий, которые могут сложиться при выполнении 
программы. 
    Кроме конструкции если — то — конец если мы будем использовать и другие 
конструкции, управляющие порядком вызовов предписаний. Почти все эти 
конструкции представлены в табл. 2.1. 
    Семантику (смысл) этих конструкций мы будем объяснять, описывая работу 
Универсального Выполнителя при их выполнении. 

    22   ГЛ. I. НАЧАЛА ПРОГРАММИРОВАНИЯ 

                                                                                                   Таблица  2.1 

                                 Основные управляющие конструкции 


                                      Четыре конструкции выбора 

    если (условие) 
    .  то   (действия) 
    конец если	

   если (условие) 
   .  то        (действия1) 
   .  иначе (действия2) 
   конец если 

   выбор 
   . при (условие1) =>  (действия 1) 
   . при (условие2> => (действия 2) 
   ................
   . при (условие N) => (действияN) 
   конец выбора	

   выбор 
   . при (условие1) =>  (действия 1) 
   . при (условие2> => (действия 2) 
   ................
   .  при (условие N) => (действияN) 
   .  иначе                  => (действия)
   конец выбора	


                                                   Шесть конструкций цикла 

    цикл 
    .   выполнять 
    .        (действия) 
    конец цикла	

    цикл пока (условие) 
    .     выполнять (действия) 
    конец цикла 

    цикл К раз 
    .   выполнять  (действия) 
    конец цикла	

    цикл К раз 
    .   пока (условие) 
    .   выполнять 
    .         (действия) 
    конец цикла 

    цикл для каждого X из М 
    .   выполнять 
    .        (действия) 
    конец цикла	

    цикл для каждого X из М 
    .   пока (условие) 
    .   выполнять 
    .   (действия) 
    конец цикла 

          В каждой из этих шести   конструкций   цикла среди   «действий»   может 
             встретиться одна или несколько конструкций 
       
                                         выход из цикла 

    Конструкции утверждение, отказ и ничего не делать 

    утверждение: <условие>       или        утв: <условие>
    отказ               
    ничего не делать 


    2. УПРАВЛЯЮЩИЕ КОНСТРУКЦИИ И УТВЕРЖДЕНИЯ     23 


    Конструкции выбора.  

   Семантика конструкций  выбора ясна  из схем рис. 2.3. 


    Рис.  2.3.  Конструкции   выбора:   а)   если — то—конец   если;   
б)  если—то — иначе — конец   если;   в)   выбор—конец    выбора;   
г)   выбор — иначе __ конец выбора 

    Циклы. 

   Конструкция цикл выполнять — конец цикла вызывает повторение тела 
цикла (т. е. действий, записанных между словами выполнять и конец цикла), 
вообще говоря, до бесконечности. Выполнение такого цикла может закончиться 
лишь в двух случаях:
  ~ возникла ситуация «отказ» при выполнении одного из действий (в этом 
случае выполнение программы вообще прекращается);
  — встретилась конструкция выход из цикла (в этом случае текст до слов конец 
цикла пропускается и далее выполняются строки, записанные после конструкции 
цикла). 
    Конструкция цикл пока — выполнять — конец цикла выполняется в 
соответствии со схемой, изображенной на рис. 2.4, 
    Конструкция цикл К раз выполнять — конец цикла заставляет Универсальный 
Выполнитель выполнить тело цикла требуемое число раз (при К = 0 тело цикла не 
выполняется ни разу). Например, программу обхода квадранта по периметру можно 
записать так:

    24 ГЛ. 1. НАЧАЛА ПРОГРАММИРОВАНИЯ


    программа прогулка 
    . дано       : | препятствия не прилегают к стенам квадранта 
    . получить: | обойти квадрант по периметру 
    .   Путник.начать работу 
    .    цикл 4 раз выполнять 
    .   .     Путник.шагать до упора 
    .   .     Путник.повернуться направо 
    .   конец цикла 
    .   Путник.кончить работу 
    конец программы 

    Обратите внимание, что эта программа и программа «прогулка» из разд. 1 — 
это два разных формальных описания (т. е. две разные программы) одной и той же 
последовательности вызовов предписаний исполнителя Путник. 
    При выполнении конструкции цикл К раз пока — выполнять — конец цикла 
Универсальный Выполпитель пытается повторить тело цикла требуемое число раз. 
Однако в отличие от предыдущей конструкции перед каждым выполнением тела цикла 
Универсальный Выполнитель анализирует условие после слова пока. Если условие 
выполнено, то тело цикла очередной раз выполняется. Если же условие не 
выполнено, то выполнение конструкции цикла завершается и выполняются действия, 
записанные после слов конец цикла. 
    Конструкции цикл для каждого... и цикл для каждого — пока... приведены для 
полноты картины. Они встретятся и будут объяснены позже. 
    Наконец, встретив конструкцию выход из цикла, Универсальный Выполнитель 
пропускает текст до слов конец цикла и выполняет действия, следующие далее. 
    Утверждение, отказ и ничего не делать. Конструкция утверждение, или утв, 
приводит к проверке записанного в ней условия. Если условие выполнено, то 
выполнение программы нормально продолжается. Если условие не выполнено, то 
Универсальный Выполнитель считает, что возникла ситуация «отказ», и прекращает 
выполнение программы. Аналогичным образом он прекращает выполнение программы, 
если встречает конструкцию отказ. 
    Конструкция ничего не делать, как и следует из ее названия, не приводит ни 
к каким действиям Универсального Выполнителя. 

    Рис.  2.4.  Конструкция цикл  —  пока  —  выполнять —  конец цикла 


    5. УПРАВЛЯЮЩИЕ КОНСТРУКЦИИ И УТВЕРЖДЕНИЯ	25 

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

    программа осторожный шаг 
    . дано        : | Путник где-то в квадранте 
    .----------------
    . получить: 
    .	если Путник.впереди свободно 
    .	.  то 
    .	.        Путник.сделать шаг 
    .	.  иначе 
    .	.       ничего не делать 
    .	конец если 
    конец программы 

    Несколько примеров программ с управляющими конструкциями 

    программа повернуться спиной к препятствию 
    . дано       : I Путник в клетке около препятствия 
    . получить: | Путник там же, спиной к препятствию 
    .----------------
    .    выбор 
    .    .   при Путник.слева      занято => Путник.повернуться направо .    .  
    .    .   при Путник.справа    занято => Путник, повернуться налево .    .   
    .    .   при Путник.впереди занято => Путник.повернуться налево 
    .    .                                                          Путник.повернуться налево 
    .    .    иначе => ничего не делать 
    .    конец выбора 
   конец программы 

    программа в левый верхний угол стола 
    . дано :        | Резчик металла включен . 
    . получить:  | резак в левом верхнем углу стола 
    .-----------------
    .    цикл пока РМ.резак не у верхнего края стола выполнять 
    .    .  РМ.шаг вверх 
    .    конец цикла 
    .    утв:   РМ.резак у верхнего края стола 
    .   цикл пока РМ.резак не у левого края стола выполнять 
    .   .  РМ.шаг влево 
    .   конец цикла 
    .  утв:   РМ.резак у верхнего края стола 
    .            и  
    .            РМ.резак у левого края стола 
    конец программы 


    26      ГЛ. 1. НАЧАЛА ПРОГРАММИРОВАНИЯ 


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

    Замечание. Теперь мы можем придать более точный смысл терминам «условие» и «действия». 

    Условие, как видно из примера программы «в левый верхний угол стола», 
может состоять из нескольких вызовов предписаний, вырабатывающих значения типа 
да/нет. Эти вызовы должны быть связаны между собой логическими связками и, 
или, не (сокращение от «неверно, что»). Допустимы также скобки для явного 
указания порядка выполнения. В условиях вида «А и В» и «А или В» вначале 
проверяется А. Если этого достаточно для проверки всего условия (в «А и В» А 
не выполнено, в «А или В» А выполнено), то В вообще не проверяется 
(предписание не вызывается). 
    Действия, как видно из примера программы «периметр квадранта», могут 
содержать не только вызовы предписаний, но и управляющие конструкции, действия 
которых в свою очередь также могут содержать управляющие конструкции, и т, д. 
Таким образом, конструкции можно вкладывать друг в друга и, вообще говоря, 
неограниченно. На практике, однако, стараются , чтобы уровень вложенности 
конструкций не превышал 2—3, так как, чем выше уровень вложенности, тем 
труднее понять программу, 
    И условия, и действия могут быть пустыми, Пустое условие считается 
выполненным. Обычно пустые условия используются вместе с комментариями, в 
которых записываются неформальные условия (см., например, программу «периметр 
квадранта»). Такие комментарии облегчают чтение и понимание программы 
человеком, но игнорируются Универсальным Выполнителем на этапе выполнения программы. 

    3. ТЕХНОЛОГИЯ «СВЕРХУ ВНИЗ»      27 

    Наконец, заметим, что в отличие от программы «прогулка» в программе 
«периметр квадранта» мы не начинаем и не кончаем работы ни с Путником, ни со 
Счетчиком. Вообще говоря, информация о том, начата ли уже. работа с 
исполнителем и надо ли кончить ее, должна записываться в дано/получить. Мы, 
однако, вместо эого установим следующее соглашение: если имя исполнителя или 
информация о состояниях его глобальных объектов фигурирует в дано/получить, то 
ни начинать, ни кончать работу с ним не надо. 

    ЗАДАЧИ И УПРАЖНЕНИЯ 

    Придумайте имена программ и напишите программы со следующими 
дано/получить: 

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

2. дано:      | Путник стоит лицом на восток в клетке над северо-западным  углом   
                    | прямоугольного   препятствия, которое не прилегает к стенам квадранта 
  получить: | положение и ориентация  Путника не изменились, в Счетчике — периметр 
                    |препжгствия 

3. дано:      | Путник где-то в квадранте 
  получить: | Путник прошагал прямо до упора, в Счетчике — число пройденных Путником 
                    | клеток (число шагов) 

4. дано:      | лист металла занимает весь стол Резчика. В первом 
                    | (верхнем)  ряду какие-то клетки прорезаны, а какие-то нет. Резак в левом 
                    | верхнем углу и поднят 
  получить: | во втором ряду прорезаны те же клетки, что и в первом. 
                    | Резак в самой левой клетке второго ряда 

5. дано:      | лист металла занимает весь стол Резчика. В первом (верхнем) ряду какие-то клетки  
                    | прорезаны, а какие-то нет. 
                    | Резак в левом верхнем углу и поднят 
  получить: | во всех рядах прорезаны те же клетки, чтр 
                    | и в первом ряду. Резак в левой клетке последнего ряда 

6. дано:      | лист  металла занимает весь стол Резчика,  Резак в левом верхнем углу и поднят 
  получить: | в листе прорезано отверстие  (трафарет)  в форме числа 4444 
