ДРоботландский Университет 
2000/2001 учебный год
Курс 31 "Азы программирования"
Корректор
------------------------------------------------
     Р О Б О Т Л А Н Д С К О Е  П Р О Г Р А М М И Р О В А Н И Е

                                  (C) А.А. Дуванов

                                      Под редакцией
                                      Ю.А. Первина

                                      Пособие   распространяется
                                      только в рамках  Роботлан-
                                      дских  Курсов  и  является
                                      объектом авторского права.

                       К О Р Р Е К Т О Р

Глава 3. Отладка программ

   Надежде Семеновне  Кук  по роду своей деятельности приходится
много работать  с  музыкальными  инструментами. Она знает, чтобы
скрипка звучала не фальшиво, ее надо  тщательно настроить. Также
и  в  программировании: для того, чтобы программа работала  пра-
вильно, ее надо тщательно отладить.
   Отладка - очень важный этап  разработки  программ.  Об этом и
пойдет сегодня основной разговор у мужской половине семьи Куков.

3.1. Корректор развлекается с котом

   Папа. Начнем  нашу  работу с такой задачи (<<perever3.kor>>):
на ленте написано трехсимвольное слово, и в начальный момент ок-
но установлено на его начало. Написать программу, которая меняет
местами первый и последний символ слова.
   Петя. Значит, если  на  ленте написано слово "кот", Корректор
должен заменить его словом "ток".
   Вася. А если на ленте записано слово "сон", Корректор превра-
тит его в слово "нос".
   Папа. Правильно!  С  условием задачи мы разобрались, давайте
приступим к решению.
   Петя. Я думаю без ящика здесь не обойтись.
   Папа. Предчувствие тебя не обмануло!
   Вася. Нужно скопировать первый символ в ящик.
                               ┬─┬
                            ┌─>│к│
                            │  ┴─┴
                            │
                     ┬─┬─┬─╦═╦─┬─┬─┬─┬─┬
                     │░│░│░║к║о│т│░│░│░│
                     ┴─┴─┴─╩═╩─┴─┴─┴─┴─┴

   Затем идти в конец слова и записать на  место последнего сим-
вола содержимое ящика. Потом...
                        ┬─┬
                        │к│─────┐
                        ┴─┴     │
                                V                                                                                       │
                     ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬
                     │░│░│░│к│о║к║░│░│░│
                     ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴

   Петя. Стоп! Посмотри, что ты натворил: последний символ стерт
с ленты безвозвратно!
   Вася. Понял. Нужно содержимое ящика записать  не на последний
символ, а рядом с ним.
                        ┬─┬
                        │к│───────┐
                        ┴─┴       │
                                  V                                                                                       │
                     ┬─┬─┬─┬─┬─┬─╦═╦─┬─┬
                     │░│░│░│к│о│т║к║░│░│
                     ┴─┴─┴─┴─┴─┴─╩═╩─┴─┴

 Затем скопировать в ящик последний символ слова:
                        ┬─┬
                        │т│<────┐
                        ┴─┴     │
                                │                                                                                       │
                     ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬
                     │░│░│░│к│о║т║к│░│░│
                     ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴
   После чего надо  идти к началу  слова и заменить  первый  его
символ на содержимое ящика:
                                ┬─┬
                            ┌───│т│
                            │   ┴─┴
                            V                                                                                          │
                     ┬─┬─┬─╦═╦─┬─┬─┬─┬─┬
                     │░│░│░║т║о│т│к│░│░│
                     ┴─┴─┴─╩═╩─┴─┴─┴─┴─┴

   Теперь перемещаем  окно  на копию первого символа, записываем
ее в ящик и стираем с ленты:
                                 ┬─┬
                                 │к│
                                 ┴─┴
                                                                                                                        │
                     ┬─┬─┬─┬─┬─┬─╦═╦─┬─┬
                     │░│░│░│т│о│т║░║░│░│
                     ┴─┴─┴─┴─┴─┴─╩═╩─┴─┴

   Осталось только сместиться на одну ячейку влево и переписать
символ из ящика на ленту:
                           ┬─┬
                           │к│──┐
                           ┴─┴  │
                                V                                                                                       │
                     ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬
                     │░│░│░│т│о║к║░│░│░│
                     ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴

   Папа. Теперь оформи свой алгоритм в виде программы.

   Вася написал на экране в программном поле следующий текст:
┌───────────────────────────────────────────────────────────┐
│ ЭТО Перевертыш                                            │
│  // Помещаем первый символ за словом                      │
│  ЯЩИК +                                                   │
│  ПОВТОРИ 3 ВПРАВО                                         │
│  ЯЩИК-                                                    │
│  // Последний символ на место первого                     │
│  ВЛЕВО                                                    │
│  ЯЩИК+                                                    │
│  ПОВТОРИ 2 ВЛЕВО                                          │
│  ЯЩИК-                                                    │
│  // Заменяем последний символ слова                       │
│  ПОВТАРИ 3 ВПРАВО                                         │
│  ЯЩИК+                                                    │
│  ПИШИ ПУСТО                                               │
│                                                           │
│  ЯЩИК_                                                    │
│ КОНЕЦ                                                     │
│                                                           │
└───────────────────────────────────────────────────────────┘

3.2. Синтаксические ошибки

Папа. Ну, запускай свою программу.
Вася нажал экранную кнопку GO и увидел на экране сообщение:
      ┌────────────────────────────────────┐
      │Неверное начало команды             │
      │или нет ключевого слова КОНЕЦ       │
      │                                    │
      └────────────────────────────────────┘
   Петя. Интерпретатор обнаружил в твоей программе  синтаксичес-
кую ошибку и выдал диагностическое сообщение.
   Вася. Какие  умные  слова  ты говоришь! Переведи, пожалуйста,
это на русский.
   Петя. Синтаксическая ошибка - это несоответствие текста твоей
программы правилам языка программирования. Интерпретатор, прежде
чем выполнять  программу,  производит  проверку ее правильности.
Сейчас он обнаружил ошибку и честно об этом сказал.
   Вася. А где же ошибка?
   Петя. Нажми кнопку на панели с сообщением или клавишу Esc.
   Вася нажал на  клавишу Esc. Сообщение пропало, а курсор уста-
новился за знаком "+" в третьей строке программы
┌──────────────────────────────────────┐
│ ЭТО Перевертыш                       │
│  // Помещаем первый символ за словом │
│  ЯЩИК +█                             │<── Курсор указывает на
│  ПОВТОРИ 3 ВПРАВО                    │    обнаруженную ошибку
│  ЯЩИК-                               │
│  // Последний символ на место первого│
│  ВЛЕВО                               │
│  ЯЩИК+                               │
│  ПОВТОРИ 2 ВЛЕВО                     │
│  ЯЩИК-                               │
│  // Заменяем последний символ слова  │
│  ПОВТАРИ 3 ВПРАВО                    │
│  ЯЩИК+                               │
│  ПИШИ ПУСТО                          │
│                                      │
│  ЯЩИК_                               │
│ КОНЕЦ                                │
│                                      │
└──────────────────────────────────────┘
   Петя. Вот видишь, интерпретатор установил курсор  в то место,
где он обнаружил ошибку.
   Вася. Да, ошибку я теперь вижу: между словом ЯЩИК и  знаком +
не  должно  быть пробела. Но почему, интерпретатор вместо  того,
чтобы прямо сказать "убери пробел", выдал такое странное сообще-
ние?
   Петя. Откуда ему знать, что ты написал команду из СКИ с ошиб-
кой? Интерпретатор решил, что слово ЯЩИК - это  имя новой проце-
дуры, и она будет описана позже. Значит, здесь - все  в порядке.
Следующий знак + он воспринял как неверный и  выдал свое сообще-
ние.
   Вася  исправил  ошибку и снова запустил программу. На  экране
снова появилось прежнее сообщение, а курсор  теперь был установ-
лен в строке:
┌───────────────────────────────────────────────────────────┐
│  ПОВТАРИ█3 ВПРАВО                                         │
└───────────────────────────────────────────────────────────┘

   Петя. Та же ситуация. Слово ПОВТОРИ написано с  ошибкой и ин-
терпретатор его "не  узнал". Он, конечно, решил, что ПОВТАРИ яв-
ляется именем новой процедуры, а цифра три, следующая за вызовом
этой процедуры - неверное начало новой команды.
   Вася, смутившись своей описки, написал команду цикла правиль-
но и снова запустил программу. Результат  опять оказался отрица-
тельным, но сообщение на экране было уже другим:
      ┌────────────────────────────────────┐
      │Не описана процедура с именем       │
      │           "ЯЩИК_"                  │
      │                                    │
      └────────────────────────────────────┘

   Курсор на программном поле установился в самый конец програм-
мы.
   Вася. Я попробую теперь сам объяснить  что произошло. Команда
из СКИ написана с ошибкой, поэтому интерпретатор не узнал ее.
   Петя. Верно. Он решил, что это вызов процедуры. Ошибку на эк-
ране интерпретатор показал в  самом  конце текста, за словом КО-
НЕЦ.  Именно  там он ожидал увидеть описание процедуры  "ЯЩИК_",
но, увы, не нашел.
   Вася исправил ошибку, запустил программу.  На  этот  раз  она
стала выполняться, но из слова "кот" получился не "ток", а непо-
нятное слово "котк".
   Вася. ???
   Петя. Синтаксических ошибок  в  твоей программе нет, и интер-
претатор выполнил ее, но в твоей программе есть логическая ошиб-
ка!

3.3. Логические ошибки.
   Вася. Что ты называешь логической ошибкой?
   Петя. Это когда твоя программа  написана  правильно  с  точки
зрения интерпретатора программ,  но делает она не совсем то, что
ты хотел. Иными словами логическая ошибка - это неправильно сос-
тавленный алгоритм или программа.
   Вася. Алгоритм мы написали правильно.
   Петя. Это так. У тебя ошибка в программе.
   Вася. А как ее найти?
   Петя. Можно запустить выполнение программы по шагам.
   Вася. Интерпретатор умеет ходить?
   Петя. Интерпретатор умеет работать в двух режимах - НЕПРЕРЫВ-
НОМ и ПОШАГОВОМ.  В непрерывном режиме он выполняет программу до
конца, не останавливаясь, а в пошаговом он прерывает работу пос-
ле выполнения каждой  команды,  отмечая на экране подсветкой то,
что ему предстоит  выполнить на следующем шаге. Наблюдая за тем,
ЧТО выполняется  на поле программ  и КАК это выполняется в среде
Корректора, легко найти место логической ошибки.
   Вася. А как запустить выполнение в пошаговом режиме?
   Петя. Переключение режима  работы интерпретатора выполняется
при  помощи  кнопки, расположенной самой первой в ряду  кнопок
около окошка редактора команд:

   ┌──┐┌──┐┌──┐ ┌──────────────────────────────────┐
   │| ││- ││GO│ │█                                 │
   └──┘└──┘└──┘ └──────────────────────────────────┘
     └───────────── кнопка установки режима выполнения программы

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

   Первое нажатие  на кнопку GO  не привело к изменениям в среде
Корректора, а  в  программном поле подсветкой отметилась команда
ЯЩИК+.

   Петя. Интерпретатор выделил сейчас команду, которую он выпол-
нит на следующем шаге.

   Вася нажал кнопку GO еще раз и увидел, как Корректор скопиро-
вал букву "к" с ленты в свой ящик.

   Выполняя  и  дальше программу по шагам, Вася увидел  неверные
действия Корректора почти  в самом конце программы и сразу понял
в чем дело: перед последней командой ЯЩИК- отсутствовала команда
ВЛЕВО. После исправления программа выглядела следующим образом:

ЭТО Перевертыш
 // Помещаем первый символ за словом
 ЯЩИК+
 ПОВТОРИ 3 ВПРАВО
 ЯЩИК-
 // Последний символ на место первого
 ВЛЕВО
 ЯЩИК+
 ПОВТОРИ 2 ВЛЕВО
 ЯЩИК-
 // Заменяем последний символ слова
 ПОВТОРИ 3 ВПРАВО
 ЯЩИК+
 ПИШИ ПУСТО
 ВЛЕВО
 ЯЩИК-
КОНЕЦ

   Вася. Сейчас я переключу  режим  и запущу Корректор на непре-
рывную работу без остановок.

   На этот раз программа выполнилась  без  ошибок  и Корректор в
результате своих трудов превратил слово "кот" в "ток".

   Папа. Я внимательно  следил за отладкой программы и вижу, что
вы с ней отлично справились. Но программа для  решения нашей за-
дачи может быть гораздо короче, если использовать команду ОБМЕН.
   Петя. Да, я забыл про эту команду из СКИ Корректора.
   Вася. А как она работает?
   Петя. Эта команда меняет местами символы, записанные в окон-
ной ячейке и ящике исполнителя.
   Вася. Да,  действительно  полезная команда. Вот новый вариант
алгоритма:

-  Поместить первый символ в ящик
-  Идти в конец слова
-  Обменять местами символы в ящике и на ленте
-  Идти в начало слова
-  Обменять местами символы в ящике и на ленте

 Ну а программа действительно получается короче:

ЭТО Перевертыш
 // Поместить первый символ в ящик
 ЯЩИК+
 // Идти в конец слова
 ПОВТОРИ 2 ВПРАВО
 // Обменять местами символы в ящике и на ленте
 ОБМЕН
 // Идти в начало слова
 ПОВТОРИ 2 ВЛЕВО
 // Обменять местами символы в ящике и на ленте
 ОБМЕН
КОНЕЦ

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