Рассмотрим разные способы решения следующей задачи. Роботу надо посадить цветы в области, имеющей форму прямоугольного треугольника заданного размера. Длина его катета заранее известна (на рисунке катет равен 6 клеткам). Сейчас мы знаем, как решать эту задачу с помощью цикла повтори. Рассмотрим другой способ, в котором используется цикл пока.

Ряд

{

int n; /* выделить место в памяти */

направо;

n = 1; /* присвоить значение переменной */

пока ( n <= 6 ) /* всего 6 строк */

{

повтори ( n ) /* длина строк меняется! */

{

вперед ( 1 );

посади;

}

направо;

вперед ( 1 );

налево;

назад ( n );

n = n + 1; /* увеличить переменную n на 1*/

}

}

направо; вперед ( 1 ); налево;

назад ( n );

}

Как и ранее, мы должны использовать вспомогательную переменную n, которая равна длине очередного ряда клеток. При этом велика вероятность того, что мы забудем присвоить ей начальное значение (n = 1;) или увеличивать ее в теле цикла (n = n+1;). Чтобы сосредоточить все операции с переменной n (она называется параметром цикла) в одном месте, используют третий вид цикла, который так и называется – цикл или for (от английского “для”), который позволяет заменить как цикл повтори, так и цикл пока.

Ряд

{

int n;

направо;

цикл ( n=1; n<=6; n=n+1 )

{

повтори ( n )

{

вперед ( 1 );

посади;

}

направо;

вперед ( 1 );

налево;

назад ( n );

}

}

направо; вперед ( 1 ); налево;

назад ( n );

}

Как видно из этой программы, все операции с переменной n теперь сгруппированы в заголовке цикла for между круглыми скобками. Три части отделяются знаком «;», так же как и конец команды:

1.  Начальное условие n=1 выполняется один раз перед началом цикла;

2.  Условие продолжения n<=6 говорит о том, при каком условии цикл будет выполняться (если в самом начале это условие неверно, то цикл не выполнится ни одного раза);

3.  Изменение переменной цикла n=n+1 - этот оператор выполняется каждый раз в конце очередного прохода тела цикла.

2  Задачи

1.  В начале значение переменной x равно 3. Как изменится x после выполнения программы:

x = 5; x = - x; x = x + 5;

2.  В начале значение переменной x равно 3, а значение y равно 5. Как изменятся x и y после выполнения программы:

y = 1; x = x + y; y = x; x = y;

3.  Посадить цветы в левом нижнем углу и вернуться обратно. Размеры прямоугольника и начальное положение Робота считать неизвестными.

4.  Решите задачу для Робота, используя цикл с параметром.

7.  Диалоговые программы

2  Что такое диалоговая программа?

До сих пор мы составляли программу для исполнителя и затем смотрели, как он ее выполняет, не имея возможности вмешаться в его работу. Чтобы скорректировать его действия, надо было дождаться, пока он закончит работу по программе (или прервать ее выполнение), исправить программу и выполнить ее снова с самого начала.

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

¨  Пользователь человек, использующий программу в своей работе.

¨  Диалоговая программа – программа, во время выполнения которой происходит диалог пользователя и программы с использованием операций ввода и вывода информации. Решения принимает человек, а программа выполняет всю рутинную работу.

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

2  Вывод на экран (задача z8-3.maz)

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

Алгоритм решения очень прост:

1)  дойти до стенки (цикл пока);

2)  дойти до края стенки (цикл пока);

3)  идти вдоль стенки, пока она не кончится, и на каждом шаге увеличивать переменную-счетчик (назовем ее n).

Когда длина найдена, надо вывести ее на специальный экран:

вывод n;

После команды Робота вывод пишут имя переменной. Но при этом на экран будет выведено только значение переменной (число). Гораздо удобнее получить на экране сообщение вроде

Длина стенки 13 клеток.

Для этого надо дополнить команду вывода так:

вывод "Длина стенки ", n, " метров.";

То есть в команде вывод можно указать несколько элементов через запятую. Это могут быть строчки в кавычках (они выводятся на экран без изменения) и имена переменных (на экран выводится значения этих переменных). Вот полная программа:

НайтиДлину

{

int n = 0;

пока ( впереди_свободно ) вперед ( 1 );

налево;

пока ( справа_стена ) вперед ( 1 );

назад ( 1 );

пока ( справа_стена )

{

назад ( 1 );

n = n + 1;

}

вывод "Длина стенки ", длина, " клеток.";

}

2  Правила использования оператора вывода

1.  Для вывода информации на экран монитора используется оператор вывод или print (от английского print – печать), после которого следует список элементов, разделенных запятыми.

2.  В списке вывода можно использовать элементы трех видов:

· текст, заключенный в кавычки – он выводится на экран без изменений;

· имя переменной, значение которой надо вывести на экран;

· арифметическое выражение – компьютер сначала вычислит его значение, а

потом выведет результат на экран.

При использовании простейшей формы оператора вывода

вывод n;

не совсем ясно, что же выводит на экран программа. Это считается плохим стилем и поэтому наша программе должна ясно написать, что же она подсчитала.

2  Ввод данных

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

ввод n;

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

Пример 1. Ввести с клавиатуры целое число и вывести на экран его квадрат.

КвадратЧисла

{

int n, x; /* объявление переменных */

вывод "Введите целое число"; /* ввод данных */

ввод n;

x = n*n; /* обработка */

вывод "Квадрат числа ", n, " равен ", x; /* вывод */

}

Обратите внимание, что в этой простейшей диалоговой программе мы выделили четыре части

1.  объявление переменных;

2.  ввод исходных данных;

3.  обработка данных (вычисления);

4.  вывод результатов.

2  Правила использования оператора ввода

1.  Для ввода переменных с клавиатуры используется оператор ввод или input (от английского input – ввод), после которого следует список элементов, разделенных запятыми.

2.  В списке ввода можно указать одно или несколько (через запятую) имен переменных, значение которых надо ввести с клавиатуры.

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

2  Задачи

1.  Автомобиль движется без остановок с постоянной скоростью из Петербурга в Москву (расстояние 650 км). Составить программу, которая позволяет ввести скорость автомобиля и находит время в пути в часах (в минутах, в часах и минутах*).

2.  У бабушки есть куры и утки, их всего 20 штук. Одна курица вести 3 кг, а одна утка – 10  кг. Составить программу, которая позволяет ввести количество кур и находит общий вес всех птиц.

3.  Автомобиль сначала ехал по шоссе 2 часа на максимальной скорости. Затем он 3 часа ехал по лесной дороге, при этом его скорость уменьшилась в 4 раза. Составить программу, которая позволяет ввести максимальную скорость автомобиля и находит расстояние, которое проехал автомобиль, и его среднюю скорость.

4.  Василий Пупкин выехал на машине в г. Мухинск. Через 3 часа у него кончился бензин и попутная машина за 2 часа притащила его в Мухинск со скоростью 20 км/ч. Составить программу, которая позволяет вести скорость автомобиля Василия в начале пути, и находит среднюю скорость, с которой Василий преодолел расстояние до Мухинска.

5.  Пограничники обнаружили на расстоянии 5 км от берега судно-нарушитель морской границы, которое уходило в сторону моря со скоростью 20 км/ч. На перехват был выслан быстроходный катер. Через 4 минуты погони у катера сломался один из двигателей, и скорость упала до 30 км/ч. Составить программу, которая позволяет вести начальную скорость быстроходного катера и находит время, которое потребовалось ему для того, чтобы догнать нарушителя.

6.  жил на рубеже XIX и XX веков. Известно, что он жил в XX веке на 53 года больше, чем в XIX. Составить программу, которая спрашивает, сколько всего лет прожил Василий Пупкин, и после этого находит год, в котором он родился?

7.  Сторож обходит прямоугольный участок за 12 минут, его скорость – 5 км/ч. Длина одной из сторон участка известна. Составить программу, которая позволяет ввести длину этой стороны в метрах и вычисляет площадь участка.

2  Вычисления с циклами

Пример 1 (задача Гаусса). Найти сумму всех натуральных чисел от 1 до 100:

.

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

Мы будем решать эту задачу «в лоб», выполнив суммирование с помощью компьютера без применения хитростей. Выделим в памяти ячейку-переменную S и в начале запишем в нее нуль.

Подпись: S

0

 
int S;

S = 0;

Затем добавим к этой ячейке последовательно 1, 2, 3 и т. д.

Подпись: SПодпись: S

1

 
Подпись: SS = S + 1;

3

 
S = S + 2;

6

 
S = S + 3;

...

5050

 
Подпись: SS = S + 100;

Когда мы выполним эту операцию 100 раз, в переменной S окажется сумма всех натуральных чисел от 1 до 100, что и требовалось. Теперь остается эти 100 сложений заменить циклом. Заметим, что в этих строчках отличается только последнее число, т. е. каждая строка имеет вид

S = S + i;

где величина i принимает значения 1, 2, 3 и т. д. до 100. Поэтому решение выглядит так

Гаусс

{

int i, S;

i = 1; /* начальное число в сумме */

S = 0; /* пока в сумме ничего нет */

повтори ( 100 )

{

S = S + i; /* добавляем очередное число к сумме */

i = i + 1; /* переходим к следующему числу */

}

вывод "S = ", S;

}

Пример 2. Рассчитать и вывести на экран таблицу значений функции

на интервале от a до b с шагом h (эти значения вводятся с клавиатуры). Для решения такой задачи удобно использовать цикл с параметром.

Таблица

{

float a, b, h, x, y; /* объявление переменных */

вывод "Введите a, b, h:"; /* подсказка для ввода */

ввод a, b, h; /* ввод исходных данных */

for (x = a; x <= b; x = x + h ) /* вычисления и вывод */

{

y = x*x + 2*x + 3;

вывод "x = ", x, " y = ", y;

}

}

2  Задачи

1.  В земле выкопано N лунок, в каждую из которых кладут некоторое количество зерен:

    на 1-ую клетку 1 зерно на 2-ую клетку 2 зерна на 3-ю клетку 4 зерна на 4-ую клетку 8 зерен

и т. д.,

в каждую следующую – в 2 раза больше, чем в предыдущую. Программа должна подсчитать, сколько всего зерен на N клетках. Число N<30 нужно ввести с клавиатуры.

Ответ: при N = 25 должно получиться зёрен.

2.  Найти сумму N чисел Фибоначчи (каждое следующее число равно сумме двух предыдущих)

1, 2, 3, 5, 8, 13,…

Число N < 40 нужно ввести с клавиатуры.

Ответ: при N=30 сумма равна 3524576.

3.  Вывести в три ровных столбика квадраты и кубы целых чисел от 5 до 25.

4.  Вычислить сумму N чисел следующей последовательности

1, 2, 4, 7, 11, 16,…

Подсказка: разница между двумя соседними числами каждый раз увеличивается на 1.

Ответ: при N = 10 сумма равна 175.

5.  Клиент положил некоторую сумму на хранение в банк при ставке 5%. Составить программу, которая позволяет ввести начальную сумму и срок хранения, и находит сумму, которая накопится на счету к концу этого срока.

8.  Процедуры

2  Зачем нужны процедуры?

Пока наши программы содержат не более 20-30 команд (операторов) и разобраться в них не составляет труда. В то же время профессиональные программы содержат тысячи и миллионы строк, и если бы они были написаны в виде одной длинной программы, их было бы практически невозможно понимать и редактировать. Даже книги всегда разбивают на главы и разделы.

Кроме того, в больших программах часто одни и те же действия (последовательности команд) должны выполняться несколько раз в разных местах программы. При этом приходится несколько раз переписывать (или копировать) их в текст. Если этот блок надо изменить, нужно вносить изменения в нескольких местах.

Таким образом, при работе с большими программами мы встречаемся с двумя проблемами:

1)  программы получаются длинные и непонятные;

2)  существуют целые группы команд, которые встречаются несколько раз в разных местах программы.

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

Фактически при создании процедуры в список команд исполнителя добавляется новая команда. Чтобы исполнитель понял ее, надо эту команду расшифровать, то есть, объяснить, что делать при получении этой команды. Важно, чтобы в конечном счете все новые команды были расшифрованы через основные команды, входящие в СКИ исполнителя.

2  Как ввести новую команду (задача z10-3.maz)?

Пример 1. Рассмотрим задачу для Робота, показанную на рисунке. Попробуем решить ее, добавляя в СКИ исполнителя нужные нам команды. Сначала надо выделить те части задачи, которые одинаковы (или, по крайней мере, похожи). Легко заметить, что в нашей задаче есть три одинаковых площадки, каждая из которых состоит из угловой стенки и трех грядок.

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

Основная программа выглядит так:

Программа

{

Угол; 

вперед(2);

налево; назад(1);

Угол; 

вперед(1);

направо; вперед(2);

направо; вперед(5);

направо; назад(2);

Угол; 

вперед(2);

}

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

перед вторым вызовом процедуры: перед третьим вызовом процедуры:

Теперь остается только объяснить Роботу, что делать, когда он встретит в программе новую команду. После основной программы мы запишем расшифровку процедуры в виде отдельного алгоритма.

Угол

{

вперед(1);посади;

повтори(2)

{

вперед(1); направо;

вперед(1);посади;

}

налево;

}

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

Пример 2. Рассмотрим еще одну задачу. Робот должен посадить цветы в конце каждого тупика (см. рисунок справа). Известно, что тупики есть только слева от Робота, справа – сплошная стена. Количество тупиков и их длины заранее неизвестны.

Идея алгоритма очень проста: Робот двигается вперед до стены, на каждом шаге проверяя, есть ли стена слева. Если ее нет, он обрабатывает тупик.

Поход

{

пока(впереди_свободно)

{

вперед(1);

если (слева_свободно)

Тупик;

}

}

Теперь остается только записать расшифровку процедуры Тупик:

Тупик

{

налево;

пока(впереди_свободно)

вперед(1);

посади;

пока(сзади_свободно)

назад(1);

направо;

}

Важно, что после выполнения процедуры Робот стоит в том же положении, что и до ее вызова. Иначе основная программа была бы неправильной.

2  Правила использования процедур

1.  Процедуры – это вспомогательные алгоритмы.

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

3.  Каждая процедура имеет имя и оформляется по тем же правилам, что и основная программа.

4.  Каждая новая команда (процедура) должна быть расшифрована. Процедуры записываются одна за другой после основной программы.

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

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

7.  Одна процедура может вызывать другую. Количество процедур неограниченно.

4  Задачи

Составить программу для исполнителя Робот с использованием процедур:

2  Процедуры с параметрами (задача z11-3.maz)

Рассмотрим задачу для Робота, показанную на рисунке справа. Мы видим два похожих квадратных участка, которые надо обработать Роботу. Однако, размеры этих участков разные, поэтому невозможно два раза использовать одну процедуру.

Тем не менее, видно, что по структуре эти участки одинаковы. Было бы хорошо, если бы мы могли сказать процедуре, квадрат какого размера следует обработать Роботу, так же, как мы указываем ему, на сколько клеток двигаться вперед или назад (например, вперед(3)).

Будем предполагать, что у Робота есть команда Квадрат, по которой он обрабатывает квадратный участок заданного размера и возвращается в исходное положение. Тогда основная программа могла бы выглядеть так:

ДваКвадрата

{

направо; вперед(1); налево;

вперед(1);/* к правому нижнему углу большого квадрата */

Квадрат(4); /* большой квадрат */

вперед(4);

налево; /* к правому нижнему углу малого квадрата */

Квадрат(3); /* малый квадрат */

}

Первые 4 строчки переводят Робота к правому нижнему углу большого квадрата – в исходное положение перед началом выполнений команды Квадрат (рисунок 1). Предположим, что по команде Квадрат(4) Робот обрабатывает большой квадрат и останавливается в таком положении, которое показано на рисунке 2.

Рисунок 1. Рисунок 2.

Для обработки второго квадрата нужно вывести Робота в исходное положение (рисунок 3) и применить команду Квадрат(3), после чего Робот сразу оказывается на Базе (рисунок 4).

Рисунок 3. Рисунок 4.

Обработку малого квадрата можно было начинать и с любого другого угла, но тогда бы пришлось вести Робота на Базу дополнительными командами.

Теперь остается написать расшифровку процедуры Квадрат, так чтобы она могла воспринимать и использовать целое число, заданное в скобках.

Квадрат ( int n )

{

повтори ( n )

{

повтори ( n )

{

вперед(1);

посади;

}

налево;

вперед(1);

направо;

назад ( n );

}

}

Как видим, в заголовке после имени процедуры в скобках указывается тип переменной величины (параметра) – в данном случае int (целое число) – и ее имя (здесь n). При вызове процедуры число, указанное в скобках, записывается в переменную n и используется в трех выделенных строчках внутри процедуры. При первом вызове n принимает значение 4, при втором – 3.

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

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

2  Правила использования процедур с параметрами

1.  В заголовке процедуры после имени в скобках перечисляются все ее параметры (величины, которые изменяются).

2.  Эти параметры имеют имена и называются формальными (поскольку неизвестны заранее и поэтому обозначены именами). Для каждого параметра указывается его тип (int, float и т. п.).

3.  Если параметров несколько, они перечисляются через запятую. Например:

Группа ( int m, int n ) { ... }

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

4  Задачи

Решите задачи, используя процедуры с параметрами:

9.  Методы составления программ

2  Метод “сверху вниз”

При использовании этого стиля можно выделить несколько этапов:

1.  Сначала проектируется основная программа, состоящая из 20-30 команд. Часто на первом этапе составляется алгоритм на естественном (русском) языке. При этом можно вводить несуществующие команды – процедуры.

2.  Затем для каждой новой процедуры пишется расшифровка так, чтобы она также состояла из 20-30 строк, при этом снова можно вводить несуществующие команды.

3.  Эта процедура повторяется до тех пор, пока все процедуры не окажутся расшифрованными, то есть пока не останется ни одной неизвестной команды.

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

Преимущества такого подхода:

q  позволяет сначала рассмотреть задачу в целом, не обращая внимание на детали

q  позволяет ограничить размер процедур так, чтобы их было легко понимать и отлаживать (находить и исправлять ошибки)

q  позволяет легко разбить программу на части, которые выполняются разными разработчиками

Недостатки:

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

q  одинаковые или похожие операции могут быть по-разному реализованы в разных частях программы

2  Метод “снизу вверх”

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

Преимущества такого подхода:

q  программа составляется на основе единой библиотеки вспомогательных процедур

Недостатки:

q  необходимо заранее продумывать набор необходимых процедур, в ходе работы он может меняться

q  сложно разбить работу на части, выполняемые одновременно разными программистами

q  сложно разрабатывать общую структуру программы, “стыковать” отдельные части

q  процедуры могут получаться слишком длинными, это затрудняет отладку

2  Комбинированный способ


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

1.  На первом этапе разрабатывается библиотека процедур самого нижнего уровня.

2.  Дальнейшее проектирование идет методом “сверху вниз”.

Таким образом, удается совместить преимущества обоих способов.

Пример составления программы

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

Программа

{

ВУгол;

повтори(4)

{

Сторона;

направо;

}

}

Здесь мы предполагаем написать две процедуры – ВУгол и Сторона. Первая должна привести Робота в левый нижний угол:

ВУгол

{

пока(сзади_свободно)

назад(1);

налево;

пока(впереди_свободно)

вперед(1);

направо;

}

Выполняя вторую, Робот обрабатывает одну сторону прямоугольника:

Сторона

{

посади;

пока(впереди_свободно)

вперед(1);

}

Заметьте, что Робот остановится перед клумбой в левом нижнем углу, поскольку логическая команда впереди_свободно вернет ложное значение перед клумбой.

Сложная задача

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

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

Разведка

{

посадить цветы и прийти на Базу;

}

Теперь надо расшифровать эту строчку через команды Робота. Удобнее всего сначала перевести Робота в один из углов прямоугольника и затем проверить каждый ряд, посадив цветы во всех клетках, где надо. При проверке надо также запомнить, где находится База, чтобы вернуться туда после прохода всех клеток.

Разведка

{

прийти в угол;

проверить каждый ряд;

прийти на Базу;

}

Будем считать, что мы начинаем проверку из юго-западного (на рисунке – левого нижнего) угла. Затем расшифруем проверку и запишем ее с помощью цикла. Тогда получаем основную программу

Разведка

{

ВУгол;

пока ( справа_свободно )

{

ПроверитьРяд;

направо; вперед(1); налево; /* к следующему ряду */

}

 

ПроверитьРяд;

НаБазу;

}

Мы ввели три новых команды – ВУгол, ПроверитьРяд и НаБазу. Теперь остается их расшифровать. Заметьте, что строчка ПроверитьРяд после цикла нужна для того, чтобы проверить самый правый ряд клеток.

Проще всего написать процедуру ВУгол:

ВУгол

{

пока ( сзади_свободно )

назад(1);

налево;

пока ( впереди_свободно )

вперед(1);

направо;

}

Как нам запомнить, где находится База? Простейший способ – записать ее координаты относительно какого-то из углов. Примем юго-западный угол за начало отсчета и будем запоминать координаты x и y (на рисунке). Они показывают, сколько шагов надо сделать из юго-западного угла на восток, а потом – на север, чтобы прийти на базу. Для этого введем специальные целые переменные x и y. Будем считать, что если идти из юго-западного угла Тогда процедура НаБазу может быть записана так (предполагается, что Робот смотрит на север):

НаБазу

{

ВУгол;

направо; вперед(x);

налево; вперед(y);

}

Процедуру проверки ряда ПроверитьРяд можно записать так

ПроверитьРяд

{

пока ( впереди_свободно )

вперед ( 1 );

ПроверитьКлетку;

пока ( сзади_свободно )

{

назад ( 1 );

ПроверитьКлетку;

}

}

Как же найти координаты x и y? Наиболее разумно делать это при проверке очередной клетки – если нашли Базу, сразу запомнили ее координаты. Таким образом, в процедуре ПроверитьКлетку надо сажать цветы, если это нужно, и запоминать положение Базы, если она найдена.

ПроверитьКлетку

{

если ( грядки ) посади;

если ( база )

запомнить положение Базы;

}

Чтобы запомнить положение Базы, мы должны установить правильные значения x и y. Таким образом, и процедура НаБазу, и процедура ПроверитьКлетку должны иметь доступ к этим переменным. Однако если мы объявили их в процедуре НаБазу, то только она может их использовать. Такие переменные называются локальными (от английского local – местный). Можно попробовать объявить их также и в процедуре ПроверитьКлетку, но при этом в памяти будут созданы еще две другие переменные, к которым имеет доступ только процедура ПроверитьКлетку. Для того, чтобы решить задачу, надо объявить глобальные переменные x и y выше основной программы.

¨  Глобальные переменные – это такие переменные, которые можно использовать во всех процедурах и в основной программе. Их надо объявлять выше основной программы.

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

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5