Алгодром


06. Алгоритмы с аргументами

ПРИМЕР
|
ВЫЗОВ ПРОЦЕДУРЫ с АРГУМЕНТАМИ
|
ПАМЯТЬ ЭВМ
|
ВЫПОЛНЕНИЕ КОМАНДЫ ВЫЗОВА
|
ЗАМЕЧАНИЯ

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


Пример алгоритма

А что если нужно нарисовать много квадратов с разными длинами сторон? Писать кучу разных процедур вида:

  алг квадрат5
нач
     опустить перо
 сместиться на вектор(0,5)
 сместиться на вектор(5,0)
 сместиться на вектор(0,-5)
 сместиться на вектор(-5,0)
  кон ,
отличающихся друг от друга только числовыми значениями параметров команд рисования? И скучно, и долго.
Как добавить этому алгоритму гибкости: возможность рисовать стороны квадрата произвольной длины?
В поисках более эффективного решения обратимся к опыту наших друзей-математиков (-физиков). Что они имеют в виду, когда пишут, например, такие формулы:
(a+b)2=a2+2ab+b2    или  (a+b)c=ac+bc ?
Каждый, изучавший алгебру, скажет: подставляя в формулу вместо букв (параметров) любые числа, мы получим верное равенство. Таким образом, одна "буквенная" формула заменяет (бесконечное) множество "однотипных" числовых равенств. Какая впечатляющая экономия места и времени!
Может быть и в программировании возможно нечто подобное: использовать буквы (параметры) в алгоритмах с тем, чтобы в нужный момент подставить вместо них необходимые числовые значения? Как Вы уже догадались, такая возможность действительно есть.

Правила алгоритмического языка позволяют, например, составить следующий алгоритм рисования квадрата с произвольной длиной стороны а (по образцу предыдущей процедуры и по плану, представленному номерами вершин на рисунке):
  алг квадрат (арг вещ а)
нач
 
   опустить перо
 сместиться на вектор(0,а)
 сместиться на вектор(а,0)
 сместиться на вектор(0,-а)
 сместиться на вектор(-а,0)
 
  кон    
Запись "алг квадрат (арг вещ а)" означает, что у алгоритма "квадрат" есть один аргумент "а", который может быть произвольным вещественным (вещ) числом. Смысл этого объявления аргумента выяснится чуть позже.
Вы встретите алгоритмы, аргументы которых могут быть лишь целыми (цел) числами; алгоритмы, аргументы которых вообще не являются числами; а также алгоритмы, у которых, кроме аргументов, есть результаты (рез). Этим, в частности, объясняется наличие упомянутых служебных слов в заголовке алгоритма с аргументами.

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

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


    Вызов процедуры с аргументами

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

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

    Чтобы сообщить (передать в процедуру) значения аргументов, следует в команде вызова вспомогательного алгоритма после его имени указать в круглых скобках значения (фактические параметры), которые следует подставить вместо его аргументов (формальных параметров).
    Например, написав в основном алгоритме вызов квадрат(5), мы заставим компьютер "подставить" вместо объявленного (для того и объявлялся) в процедуре квадрат аргумента а число 5, указанное в скобках в команде вызова. При этом тело нашего алгоритма-образца чудесным образом превратится в тело алгоритма квадрат5, с которого мы начали. Теперь понятно, каков будет результат исполнения команд вызова квадрат(4), квадрат(9.6) и т.п.
    Ясно также, что наша процедура действительно способна рисовать квадраты любого размера при ее вызове с соответствующим фактическим значением параметра.

    Осталось только уточнить, как именно исполняются подобные команды вызова. Говоря ранее о разделении труда, мы уже выяснили, что исполнение команд вызова возлагается на ЭВМ, а не на исполнителя, способного лишь выполнть последовательно поступающие от компьютера команды: "опустить перо", "сместиться на вектор ...", "поднять перо" и т.д. Однако, прежде чем мы сможем разобраться в действиях ЭВМ при работе с аргументами, следует познакомиться со схематическим устройством памяти компьютера.


    Модель памяти ЭВМ

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

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

    При выполнении, например, команды вызова квадрат(4)компьютер

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


    Выполнение команды вызова
    вспомогательного алгоритма с аргументами

    Теперь мы можем точно сформулировать как ЭВМ выполняет указанную команду:

    1. На время выполнения вспомогательного алгоритма выполнение основного алгоритма приостанавливается.
    2. Перед началом выполнения вспомогательного алгоритма ЭВМ отводит для него специальное место в памяти.
    3. ЭВМ устанавливает значения аргументов, указанные в команде вызова в основном алгоритме.
    4. Выполняется вспомогательный алгоритм.
    5. После окончания выполнения вспомогательного алгоритма все, что с ним связано стирается из памяти.
    6. Возобновляется выполнение основного алгоритма.

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

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


    Замечания

    1. В примере Вы встретились с процедурой, имеющей два аргумента. При вызове такой процедуры важно правильно задать порядок следования фактических параметров. Соответствие между объявленными в заголовке алгоритма аргументами и их значениями в команде вызова устанавливается по порядку их следования. Понятно различие в результатах исполнения команд вызова прямоугольник(40,15) и прямоугольник(15,40)?
    2. Аргументы алгоритма можно использовать в любых командах, где могут быть числа: и сместиться в точку...,  и   нц ... раз. Например, с помощью процедуры
        алг поход (арг цел m)
      нач
        нц m раз
        вправо
      кц
        кон
      можно переместить Робота на любое заданное число шагов. Обратите внимание, что без использования аргумента подобный алгоритм составить невозможно. Таким образом, алгоритмы с аргументами бывают полезны не только для рисования подобных фигур.


    |
    |
    |
    |