Понятие о структурном программировании. Модульный принцип программирования. Принципы проектирования программ сверху вниз и снизу вверх. Подпрограммы
Основная идея структурного программирования состоит в том, что структура программы должна отражать структуру решаемой задачи, чтобы алгоритм был ясно виден из исходного текста программы. Следовательно, надо разбить программу на последовательность модулей, каждый из которых выполняет одно или несколько действий. Требование к модулю – чтобы его выполнение начиналось с первой команды и заканчивалось последней. Модульность – это основная характеристика структурного программирования. А для этого надо иметь средства для создания программы не только с помощью трех основных алгоритмических конструкций, но и с помощью средств более точно отражающих конкретную структуру алгоритма.
С этой целью в программирование введено понятие вспомогательного алгоритма или подпрограммы – набора операторов, выполняющего заданные алгоритмические действия и не зависящего от других частей исходного кода. Программа разбивается на множество подпрограмм, каждая из которых выполняет одно из действий исходного кода. Комбинируя эти блоки, удается сформировать итоговый алгоритм уже не из операторов, а из законченных блоков. Обращаться к блокам надо по названиям (именам подпрограмм), а название несет смысловую нагрузку. Например, в конкретном языке программирования запись Call Summa может означать означает обращение к подпрограмме с именем Summa, а Call – оператор вызова подпрограммы.
При структурном подходе к составлению алгоритмов и программ используются три основных типа алгоритмов: условные, циклические алгоритмы и подпрограммы. Структурированными считаются алгоритмы и программы, составленные с использованием только этих трех типов алгоритмов, при этом для записи циклов и условий должна использоваться ступенчатая запись. Например:
Если a>b то
Вывод "Первое число больше"
Иначе
Вывод "Второе число больше"
Конец если
Алгоритм считается неструктурированным, если нет ступенчатой записи или если при создании программы использован оператор безусловного перехода GoTo – переход к метке, т.е., структурное программирование – это программирование безGoTo.
Основным принципом технологии структурного программирования является нисходящее программирование - это программирование с использованием подпрограмм, которое позволяет вести разработку приложения "сверху вниз", от более общих задач к более частным. При проектировании сверху вниз программа строится с помощью последовательных уточнений. Этот процесс начинается с самого общего утверждения об ее абстрактной функции, такого как "Оттранслировать программу в машинный код" или "Обработать команду пользователя" и продолжается путем последовательных шагов уточнения. На каждом шаге уровень абстракции получаемых элементов должен уменьшаться, каждая операция на нем разлагается на композицию одной или нескольких более простых операций.
Такой подход обеспечивает хорошее соответствие проекта его начальной спецификации, но не всегда способствует его эффективному повторному использованию. Модули разрабатываются в ответ на отдельные возникающие подзадачи и, как правило, являются не более общими, чем к этому их вынуждает непосредственный контекст.
Проектирование, имеющее в виду возможность повторного использования, подразумевает построение наиболее общих, по возможности, компонент, из которых затем составляются системы. Этот процесс идет снизу вверх (сначала строятся объекты, лишь затем из них конструируется программа) и противоположен идее проектирования сверху вниз, требующей начинать с определения задачи и выводить ее решение путем последовательных уточнений.
Вместо поиска самой верхней функции системы будут анализироваться типы входящих в нее объектов. Проектирование системы будет продвигаться вперед путем последовательного улучшения понимания классов этих объектов. Это процесс построения снизу вверх устойчивых и расширяемых решений для отдельных частей задачи и сборки из них все более и более мощных блоков будет продолжаться до тех пор, пока не будет получен окончательный блок, доставляющий решение первоначальной задачи. При этом можно надеяться, что оно не является единственно возможным: если правильно применять метод, то те же компоненты, собранные по-другому и, возможно, объединенные с другими, окажутся достаточно общими, чтобы получить в качестве побочного продукта также и решения каких-то новых задач.
Таким образом, проектирование снизу вверх основано на объектах и приводит к концепциям объектно-ориентированного программирования (см. п. 1.4).
Теперь рассмотрим подробнее механизм подпрограмм, являющийся основой как классического структурного, так и объектно-ориентированного программирования.
Кроме имени подпрограмма может иметь параметры, которые называются формальными. Если имя служит для того. чтобы уникальным образом идентифицировать подпрограмму, то формальные параметры, которые напоминают переменные математических функций, выполняют роль ее входных и выходных данных.
Формальные параметры должны быть выбраны таким образом, чтобы ими был исчерпан весь набор необходимых входных и выходных величин. Нередко один и тот же параметр может оказаться входным и выходным одновременно. Например, на вход такого алгоритма может быть подан массив для обработки, а на выходе он может предстать в измененном виде как выходной параметр.
Рис. 11. Подпрограмма
Первый элемент блок-схемы на рис. 11, в отличие от ранее рассмотренных примеров, где этот блок имел наименование “Начало”, включает имя подпрограммы Warn и один формальный параметр с именем i. С помощью этого имени подпрограмма может быть вызвана из другой подпрограммы или главной программы.
Из схемы видно, что если на вход подпрограммы Warn подать i=0, то она в блоке 3 выдаст сообщение "Введите данные". При любом другом i будет выведено сообщение "Конец расчетов". Этим исчерпываются возможности подпрограммы Warn.
На рис. 12 дана схема головного алгоритма (первый блок имеет наименование "Начало"). Этот алгоритм в блоках 2 и 8 обращается к процедуре Warn. При этом фактические параметры - константы 0 и 1 – поочередно подставляются на место формального параметра i.
Рис. 12. Головной алгоритм и вызов подпрограммы
Обычно при обучении программированию различают подпрограммы двух видов: процедуры и функции. Процедуры оформляются как отдельные независимые части программного кода, просто выполняющие последовательность операторов. Например, процедура вычисления суммы двух чисел, обозначенных a и b, могла бы быть описана следующим образом:
Процедура Summa (a,b)
c = a + b
Вывод с
Конец Summa
Здесь Summa – это назначенное программистом имя подпрограммы-процедуры, а в скобках указаны формальные параметры a и b. Соответственно, обращение из главной программы к процедуре осуществляется по имени с перечнем в скобках фактических параметров, которые ей передаются, например, оператор
Summa(x,y)
может означать вызов процедуры с передачей ей фактических параметров x и y, которые будут подставлены на место формальных параметров a и b соответственно, так что процедура найдет и напечатает значение x+y. Процедура всегда вызывается отдельным оператором.
Функция, в отличие от процедуры, всегда имеет один выходной параметр, следовательно, если этот параметр – скалярный (не является массивом), функция может быть вызвана непосредственно в процессе вычисления выражения и справа от знака присваивания, например, выражение y:=max(sin(x),cos(x)) демонстрирует вызов трех функций – sin и cos для вычисления синуса и косинуса от величины x и затем функции max, которая найдет большее из этих двух значений.
Подпрограммы необходимы при составлении алгоритма решения сложной задачи, так как позволяют решать задачу "по частям" или коллективно. Кроме того, их применение уменьшает объем программы за счет неоднократного использования подпрограмм для выполнения повторяющихся расчетов.
Приведем пример.
Пусть требуется составить на структурированном языке алгоритм вычисления периметра треугольника, если известны координаты его вершин (треугольник лежит на плоскости).
Обозначим координаты вершин xA, yA, xB, yB, xC, yC и ввод их значений осуществим в главной программе. Пусть AB -расстояние между точками A и B, BC - между B и C, AC - между A и С, а Р – периметр. Периметр вычислим по известной формуле Р=AB+BC+AC, а расстояние же между двумя точками вычислим по формуле: . Вычисление расстояния между двумя точками вынесем в подпрограмму-функцию, назовем ее Длина, а формальные аргументы подпрограммы – функции обозначим через x1, y1, x2, y2. Тогда для вычисления AB, BC и AB надо три раза обратиться к подпрограмме-функции, передав ей значения фактических аргументов, сначала координаты, например, точек A и B, затем B и C, A и C.
Составим подпрограмму-функцию:
функция длина(x1, y1, x2, y2)
длина=d
конец функции
Основная программа:
начало программы
ввод координат вершин xA,yA,xB,yB,xC,yC.
P=длина(xA,yA,xB,yB)+длина(xB,yB,xC,yC)+
длина(xA,yA,xC,yC)
вывод P
конец программы.
В ряде языков, например, в C++, понятие процедуры (но не функции) отсутствует. Аналогом процедуры является функция со специальным типом void (не возвращающая никакого значения).