На прошлом занятии, уважаемый подписчик, мы с вами рассмотрели построение линейных алгоритмов на АЯ с использованием команды присваивания.
Теперь мы изучим применение ещё одной команды, которая относится к классу простых – команды обращения к алгоритмам-процедурам. При этом мы увидим, как с помощью одних алгоритмов можно строить другие, более сложные алгоритмы.
ОБРАЩЕНИЯ К АЛГОРИТМАМ
1. Для чего нужны обращения к алгоритмам?
Любой отдельно взятый алгоритм следует рассматривать не более чем формализованное описание условия соответствующей задачи и процесса её решения. При этом, как уже говорилось при определении основных понятий алгоритмического языка (см. занятие 3), заголовок алгоритма определяет его с внешней стороны, а основная часть передаёт его внутреннее содержание.
Параметры алгоритма, представленные в его заголовке, будем называть формальными. Считается, что формальные параметры алгоритма доступны извне. Это значит, что именно через их посредство алгоритм может получить значения исходных данных и выдать значения результатов.
Реализация процесса решения задачи в соответствии с описанным алгоритмом её решения называется выполнением данного алгоритма.
Чтобы выполнение алгоритма стало возможным, необходимо, во-первых, указать какие-то конкретные значения для его аргументов, а во-вторых, указать конкретные переменные, которые должны получить значения его результатов.
Указанные конкретные величины, которые “подставляются” в алгоритм с целью его выполнения, называются фактическими параметрами алгоритма. Такая “подстановка” оформляется в виде, так называемого, обращения к алгоритму. При этом говорят, что посредством обращения к алгоритму осуществляют передачу ему значений аргументов
и приём от него значений результатов.
Подводим итог. Чтобы решить задачу, необходимо выполнить алгоритм её решения. В свою очередь, чтобы сделать возможным выполнение алгоритм, следует записать обращение к нему (к алгоритму следует обратиться).
Иными словами говоря, обращения к алгоритмам нужны для получения результатов решения соответствующих задач при тех или иных исходных данных.
Но, это ещё не всё. И, более того, не самое главное.
Обращения к алгоритмам нужны не только для их выполнения, но и для построения других более сложных алгоритмов.
В последнем случае алгоритм, к которому обращаются, условно называют вспомогательным. В роли вспомогательного может выступать любой алгоритм, в том числе и тот, который сам использует какие-то другие вспомогательные алгоритмы. Тот же алгоритм, который обращается ко вспомогательным, называют основным.
Если вспомогательный алгоритм оформлен в виде алгоритма-процедуры, то обращение к нему имеет вид отдельной команды. Такая команда называется командой обращения к алгоритму-процедуре (командой вызова алгоритма-процедуры).
Однако во многих случаях значительно целесообразнее иметь возможность включать обращения ко вспомогательным алгоритмам непосредственно в состав тех или иных выражений. При этом основной алгоритм становится более компактным и понятным, уменьшается количество использованных переменных.
Чтобы обращения к некоторому алгоритму можно было включать в состав выражений, этот алгоритм должен быть оформлен как алгоритм-функция. Обращение к алгоритму-функции называют также вызовом функции.
2. Правила записи и выполнения обращений к алгоритмам.
Команда обращения к алгоритму-процедуре предназначена для вычисления значений переменных, указанных в качестве результатов в составе фактических параметров обращения.
Формально по своему внешнему виду команда обращения к алгоритму-процедуре совпадает с заголовком этого алгоритма, в котором опущены служебные слова алг, арг, рез, комментарии дано и надо, а также наименования типов, причём
на местах формальных параметров стоят перечисленные через запятую фактические параметры.
В любом случае обращения к алгоритму-процедуре список фактических параметров команды обязательно должен совпадать со списком формальных параметров алгоритма по следующим признакам:
количественно;
по порядку следования параметров в соответствии с их смыслом;
по типам параметров с учётом условий совместимости.
При этом в команде обращения к алгоритму-процедуре на местах формальных параметров-аргументов могут стоять фактические параметры не только в виде переменных, но и в виде любых выражений соответствующего типа. На местах же формальных параметров-результатов могут стоять фактические параметры только в виде переменных.
Правило выполнения команды обращения к алгоритму-процедуре:
формальным параметрам-аргументам присваиваются значения соответствующих фактических параметров;
выполняется алгоритм, к которому указано обращение;
фактическим параметрам-результатам присваиваются значения соответствующих формальных параметров.
На упомянутые присваивания при выполнении команды обращения к алгоритму-процедуре действуют следующие ограничения, называемые условиями совместимости:
при присваивании параметрам-аргументам справедливы те же условия совместимости, что и для обычной команды присваивания;
при присваивании параметрам-результатам требуется точное совпадение типов.
Всё вышесказанное касается и обращений к алгоритмам-функциям с учётом того, что эти обращения указываются в качестве величин в составе выражений.
3. Техника обращения к алгоритмам-процедурам и алгоритмам-функциям.
Всё, что нам здесь нужно, продемонстрировано на нижеследующем примере.
Построим алгоритм-процедуру вычисления произведения двух целых чисел.
алг П_П ( арг A, B: цел; рез П: цел )
нач
П := A * B
кон
В алгоритме П_П (Произведение в виде Процедуры) для обозначения заданных целых чисел выбраны переменные A и B, для обозначения результата выбрана переменная П. Все переменные – целого типа. Для решения задачи достаточно использования одной команды присваивания.
Запишем решение той же задачи также в виде алгоритма-функции.
алг П_Ф ( A, B: цел ): цел
нач
П_Ф := A * B
кон
В алгоритме П_Ф (Произведение в виде Функции) значение результата получает имя самой функции. Обратите внимание, что для этого имя функции использовано в левой части команды присваивания, решающей задачу.
Теперь построим алгоритм вычисления по формуле y = A * B + C * D, в которой A, B, C, D
– целочисленные переменные. Этот алгоритм запишем только в виде функции. Это возможно, поскольку результатом вычисления есть единственное значение y целого типа.
Обратим внимание, что для вычисления значения выражения нужно два раза вычислять произведение двух целых чисел. Воспользуемся для этого рассмотренными выше алгоритмами, как вспомогательными. Сделаем это двумя способами: с использованием вспомогательного алгоритма-процедуры П_П и с использованием вспомогательного алгоритма-функции П_Ф.
алг Сп_1 ( A, B, C, D: цел): цел
нач П1, П2: цел
П_П(A, B, П1)
П_П(C, D, П2)
Сп_1 := П1 + П2
кон
Алгоритм Сп_1 (Способ 1) имеет аргументами переменные A, B, C, D целого типа и оформлен в виде целочисленной функции. Для вычисления произведений A * B и C * D в алгоритме дважды использовано обращение ко вспомогательному алгоритму-процедуре П_П. Фактические параметры первого обращения – переменные A и B. В результате их перемножения с помощью алгоритма П_П получаем результат, для обозначения которого использована промежуточная переменная П1. Совершенно аналогично второе обращение к алгоритму П_П даёт результат перемножения чисел Cи D, обозначенный промежуточной переменной П2. Типы упомянутых промежуточных переменных П1 и П2 указаны в строке со служебным словом нач. Окончательный результат, равный сумме П1 + П2, присваивается имени функции последней командой алгоритма.
Теперь для решения этой же задачи воспользуемся вспомогательным алгоритмом-функцией П_Ф.
алг Сп_2 ( A, B, C, D: цел ): цел
нач
Сп_2 := П_Ф(A, B) + П_Ф(C, D)
кон
Алгоритм Сп_2 (Способ 2) имеет такой же заголовок, что и алгоритм СП_1. В нём для вычисления произведений A * B и C * D дважды использовано обращение ко вспомогательному алгоритму-функции П_Ф. Оба обращения указаны в составе выражения, решающего задачу в целом. Значение этого выражения присваивается имени функции Сп_2. Совершенно очевидно, что данный алгоритм гораздо более компактен и понятен по сравнению с предыдущим. Важно также то, что он не использует промежуточных переменных.
В заключение вспомним, что перед нами ставилась задача вычисления по формуле y = A * B + C * D. Для вычисления выражения в правой части у нас имеются функции Сп_1 и Сп_2. Однако нигде до сих пор не фигурировала переменная у, значение которой необходимо было получить. Эта проблема решается очень просто: для получения значения переменной y следует обратиться к функции
Сп_1 или Сп_2. Это можно сделать с помощью одной из команд присваивания: y := Сп_1(A,B,C,D) или y := Сп_2(A,B,C,D).
В качестве тренировки алгоритм вычисления по формуле y = A * B + C * D, в которой A, B, C, D – целочисленные переменные, запишите в виде процедуры.
Теперь мы знаем достаточно для того, чтобы эффектно решить следующую задачу: построить алгоритм, определяющий, на сколько изменится значение заданной функции (см. функцию к базовому алгоритму L-1 ЗначФункции), если значение аргумента x увеличить вдвое.
Для вычисления заданной функции мы этим алгоритмом (см. занятие 7) и воспользуемся. Его заголовок имеет вид алг ЗначФункции( a, x: вещ): вещ. Если, в соответствии с правилами, записать обращение к
этому алгоритму в виде ЗначФункции (a, x), то будет получено значение функции для некоторых заданных значений переменных aи x. А обращение к этому алгоритму в виде ЗначФункции (a, 2 *x) даёт значение функции, соответствующее удвоенному значению аргумента xпри том же значении аргумента a.
Поскольку алгоритм L-1 ЗначФункции оформлен в виде функции, то оба обращения к нему должны быть указаны в составе общего выражения в правой части команды присваивания. Таким образом, нужный нам алгоритм приобретает вид
Разумеется, самостоятельного значения алгоритм Разность не имеет. Он имеет смысл только в совокупности с алгоритмом L-1 ЗначФункции.
4. Метод последовательного уточнения.
Как мы только что видели, при построении одних алгоритмов могут использоваться обращения к другим вспомогательным алгоритмам. Такая возможность является основой структурного подхода к построению алгоритмов и имеет чрезвычайно большое значение по следующим причинам:
обеспечивается высокое качество алгоритмов с точки зрения их правильности, понятности, гибкости и эффективности;
становится возможным использование ранее разработанных алгоритмов из состава библиотек алгоритмов;
облегчается построение сложных алгоритмов путём их разбиения на функционально самостоятельные блоки.
Процесс разработки алгоритма методом последовательного уточнения состоит в том, что сначала алгоритм решения задачи в целом представляется на уровне использования некоторых сложных укрупнённых объектов, в частности, команд и функций. На каждом очередном уровне применения метода каждый из сложных укрупнённых объектов уточняется путём использования
более простых, но опять же таки укрупнённых объектов. На самом последнем уровне все простые укрупнённые объекты должны быть представлены элементарными объектами (стандартными командами и функциями) АЯ. Основным средством представления укрупнённых объектов любого уровня сложности является язык обращения ко вспомогательным алгоритмам.
В качестве простейшего примера применения метода последовательного уточнения построим алгоритм, который, во-первых, должен вычислять диаметр большой трубы, заменяющей по пропускной способности две малых трубы диаметрами D1 и D2, а во-вторых, вычислять диаметр огромной трубы, заменяющей две больших.
Известно, что пропускная способность трубы прямо пропорциональна площади её сечения. Поэтому, решая задачу, будем учитывать площади сечения рассматриваемых труб.
Из условия задачи видно, что нам нужно будет дважды заменять две трубы одной. Поэтому на начальном этапе решения задачи предположим, что в нашем распоряжении имеется некоторый алгоритм Замена ( D1, D2:вещ ):
вещ, который вычисляет диаметр трубы, способной заменить две другие трубы диаметрами D1 и D2.
Тогда алгоритм Трубы, решающий основную задачу, выглядит так:
В алгоритме Трубы, оформленном в виде процедуры, переменные Dбольш и Dогром обозначают диаметры большой и огромной труб соответственно, которые необходимо получить в результате решения задачи.
Вспомогательная задача.Построить алгоритм вычисления диаметра трубы, заменяющей по пропускной способности две другие трубы диаметрами D1 и D2.
Чтобы одна труба могла заменить две, площадь её сечения должна быть равна суммарной площади сечения заменяемых труб. Так как площадь круга диаметром D выражается формулой S = π* D2 / 4, то суммарная площадь сечения заменяемых труб диаметрами D1 и D2 равна π * ( D12 + D22 ) / 4. С другой
стороны, если известна площадь круга S, то та же формула позволяет найти его диаметр, а именно: D = Sqrt ( 4 * S / π ). В целом вспомогательный алгоритм Замена выглядит так:
алгЗамена ( D1, D2:вещ ): вещ
начS: вещ
S := Pi * ( D1* D1 + D2* D2 ) / 4
Замена := 2 * Sqrt ( S / Pi )
кон
В качестве комментария отметим, что как алгоритм Замена, так и алгоритм Трубы не теряют работоспособности при произвольных D1 и D2. Но, естественно, результаты алгоритмов имеют смысл только при D1³0 и D2³0.
Таким образом, мы обнаружили принципиальную возможность детализации сложных проектов методом последовательного уточнения на основе применения вспомогательных алгоритмов.
Уважаемый подписчик! Чтобы получить более подробное изложение материала занятия №8 “Обращения к алгоритмам”, перейдите по ссылке http://a-morgun.narod.ru/a06-01/a0006-0001-0006.html. Там вы найдёте подробный разбор примеров построения и других линейных алгоритмов
с использованием вспомогательных алгоритмов.
При необходимости задать вопрос, проконсультироваться, уточнить или обсудить что-либо обращайтесь через Гостевую книгу моего персонального сайта http://a-morgun.narod.ru