Структурное программирование. Принципы структурного программирования Структурированное программирование

КОНСПЕКТ ОБЗОРНОЙ ЛЕКЦИИ

Для студентов специальности
Т1002 «Программное обеспечение информационных технологий»

(А.М.Кадан , к.т.н., доцент)

Вопрос №34.
Характеристика основных методологий разработки программного обеспечения

1. Методология и технология программирования.

2. Императивное программирование.

2.1. Модульное программирование.

2.2. Структурное программирование.

3. Метод объектно-ориентированного программирования.

Методология и технология программирования

Приведем основные определения.

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

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

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

Жизненный цикл программного обеспечения – это весь период его разработки и эксплуатации, начиная с момента возникновения замысла и заканчивая прекращением ее использования.

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

Из четырех широко известных в настоящее время методологий программирования – императивного, объектно-ориентированного, логического, функционального - рассмотрим то, чему вас учили - методологии императивного и объектно-ориентированного программирования.

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

Технологии удобно характеризовать в двух измерениях - вертикальном (представляющем процессы) и горизонтальном (представляющем стадии).

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

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

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

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

Императивное программирование

Императивное программирование - это исторически первая методология программирования, которой пользовался каждый программист, программирующий на любом из «массовых» языков программирования – Basic , Pascal , C .

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

Методы и концепции

· Метод изменения состояний - заключается в последовательном изменении сос тояний. Метод поддерживается концепцией алгоритма.

· Метод управления потоком исполнения - заключается в пошаговом контроле управления. Метод поддерживается концепцией потока исполнения.

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

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

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

Традиционное средство структурирования - подпрограмма (процедура или функция). Подпрограммы имеют параметры и локальные определения и могут быть вызваны рекурсивно. Функции возвращают значения как результат своей работы.

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

Императивные языки программирования. Императивные языки программирования манипулируют данными в пошаговом режиме, используя последовательные инструкции и применяя их к разнообразным данным. Считается, что первым алгоритмическим языком программирования был язык Plankalkuel (от plan calculus), разработанный в 1945-1946 годах Конрадом Цузе (Konrad Zuse ).

Наиболее известные и распространенные императивные языки программирования, большинство из которых было создано в конце 50-х - середине 70-х годов XX века, представлены на рисунке. Обратите внимание на пустое место на рисунке, соответствующее 80-м и 90-м годам прошлого века. Это период увлечения новыми парадигмами, и императивных языков в это время практически не появлялось.

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

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

Рекомендации по литературе. Особенности императивного программирования изложены в огромном количестве книг. Наиболее систематично они приведены в работе "Универсальные языки программирования. Семантический подход" [Калинин, Мацкевич 1991].

Модульное программирование

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

Концепции модульного программирования. В основе модульного программирования лежат три основных концепции:

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

Аксиома модульности Коуэна. Модуль - независимая программная еди ница, служащая для выполнения некоторой определенной функции программы и для связи с остальной частью программы. Программная единица должна удовлетворять следующим условиям:

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

синтаксическая обособленность, т. е. выделение модуля в тексте син таксическими элементами;

семантическая независимость, т. е. независимость от места, где про граммная единица вызвана;

общность данных, т. е. наличие собственных данных, сохраняющихся при каждом обращении;

полнота определения, т. е. самостоятельность программной единицы.

Сборочное программирование Цейтина . Модули - это программные кирпичи, из которых строится программа. Существуют три основные пред посылки к модульному программированию:

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

потребность организационного расчленения крупных разработок;

возможность параллельного исполнения модулей (в контексте парал лельного программирования).

Определения модуля и его примеры. Приведем несколько дополнительных определений модуля.

  • Модуль - это совокупность команд, к которым можно обратиться по имени.

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

Функциональная спецификация модуля должна включать:

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

· описание семантики функций, выполняемых модулем по каждому из его входов.

Разновидности модулей. Существуют три основные разновидности модулей:

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

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

a) задачи в языке программирования Ada ;

b) кластер в языке программирования CLU ;

c) классы в языках программирования C++ и Java .

3) "Большие” (логические) модули, объединяющие набор "средних" или "маленьких" модулей. Примеры "больших" модулей в языках программи рования:

a) модуль в языке программирования Modula-2;

b) пакеты в языках программирования Ada и Java .

Набор характеристик модуля предложен Майерсом [Майерс 1980]. Он состоит из следую щих конструктивных характеристик:

1) размера модуля;

В модуле должно быть 7 (+/-2) конструкций (например, операторов для функций или функций для пакета). Это число берется на основе представлений психологов о среднем оператив ном буфере памяти человека. Символьные образы в человеческом мозгу объединяются в "чанки " - наборы фактов и связей между ними, запоминаемые и извлекаемые как единое целое. В каждый момент времени человек может обр абатывать не более 7 чанков .

Модуль (функция) не должен превышать 60 строк. В результате его мож но поместить на одну страницу распечатки или легко просмотреть на экране монитора.

2) прочности (связности) модуля;

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

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

Функциональная связность. Модуль с функциональной связностью реализует одну какую-либо определенную функцию и не может быть разбит на 2 модуля с теми же типами связностей.

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

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

Обратим внимание на то, что средства для задания информационно прочных модулей отсутствовали в ранних языках программирования (например, FORTRAN и даже в оригинальной версии языка Pascal ). И только позже, в языке програм мирования Ada , появился пакет - средство задания информационно прочного модуля.

3) сцепления модуля с другими модулями;

Сцепление (coupling ) - мера относительной независимости модуля от других модулей. Независимые модули могут быть модифицированы без переделки других модулей. Чем слабее сцепление модуля, тем лучше. Рассмотрим раз личные типы сцепления.

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

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

· Сцепление по простым элементам данных.

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

4) рутинности (идемпотентность, независимость от предыдущих обраще ний) модуля.

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

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

· В большинстве случаев делаем модуль рутинным, т. е. независимым от предыдущих обращений.

· Зависящие от предыстории модули следует использовать только в тех случаях, когда это необходимо для сцепления по данным.

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

Структурное программирование.

Структурное программирование (СП) возникло как вариант решения проблемы уменьшения СЛОЖНОСТИ разработки программного обеспечения .

В начале эры программирования работа программиста ничем не регламентировалась. Решаемые задачи не отличались размахом и масштабностью, использовались в основном машинно-ориентированные языки и близкие к ним язык типа Ассемблера, разрабатываемые программы редко достигали значительных размеров, не ставились жесткие ограничения на время их разработки.

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

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

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

Подход базируется на двух основных принци пах:

  • Последовательная декомпозиция алгоритма решения задачи сверху вниз.
  • Использование структурного кодирования.

Напомним, что данная методология является важнейшим развитием импе ративной методологии.

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

Методы и концепции, лежащие в основе структурного программирования. Их три

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

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

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

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

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

Теорема о структурировании (Бёма-Джакопини ( Boem - Jacopini )): Всякую правильную программу (т.е. программу с одним входом и одним выходом без зацикливаний и недостижимых веток) можно записать с использованием следующих логических структур ‑ последовательность, выбора и повторение цикла

Следствие 1: Всякую программу можно привести к форме без оператора goto .

Следствие 2: Любой алгоритм можно реализовать в языке, основанном на трех управляющих конструкциях-п оследовательность, цикл, повторение.

Следствие 3: Сложность структурированных программ ограничена, даже в случае их неограниченного размера.

Структурное программирование- это не самоцель. Его основное назначение- это получение хорошей ("правильной") программы, однако даже в самой хорошей программе операторы перехода goto иногда нужны: например - выход из множества вложенных циклов.

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

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

Рекомендации по литературе. Одной из наиболее известных работ в этой области является статья "Заметки по структурному программированию" [Дейкстра 1975]. Методы структурного программирования подробно рассмотрены в книге "Теория и практика структурного прграммирования " [Лингер , Миллс, Уитт 1982]. Практику структурного программирования можно изучать по книге "Алгоритмы + структуры данных = программы" [Вирт 1985]. Философия визуального структурного программирования подробно изложена в работе [Паронджанов 1999].

Метод объектно-ориентированного программирования.

Метод структурного программирования оказался эффективен при написании программ «ограниченной сложности». Однако с возрастанием сложности реализуемых программных проектов и, соответственно, объема кода создаваемых программ, возможности метода структурного программирования оказались недостаточными.

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

Чтобы писать все более сложные программы, необходим был новый подход к программированию. В итоге были разработаны принципы Объектно-Ориентированного Программирования. OOP аккумулирует лучшие идеи, воплощённые в структурном программировании, и сочетает их с мощными новыми концепциями, которые позволяют по-новому организовывать ваши программы.

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

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

Объектно-ориентированные программы называют «программами, управляемыми от событий», в отличие от традиционных программ, называемых «программам, управляемыми от данных».

Основные методы и концепции ООП

· Метод объектно-ориентированной декомпозиции – заключается в выделении объектов и связей между ними. Метод поддерживается концепциями инкапсуляции, наследования и полиморфизма.

· Метод абстрактных типов данных – метод, лежащий в основе инкапсуляции. Поддерживается концепцией абстрактных типов данных.

· Метод пересылки сообщений – заключается в описании поведения системы в терминах обмена сообщениями между объектами. Поддерживается концепцией сообщения.

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

Объект имеет набор обработчиков сообщений (набор методов). У объекта есть поля – персональные переменные данного объекта, значениями которых являются ссылки на другие объекты. О одном из полей объекта хранится ссылка на объект-предок, которому переадресуются все сообщения, не обработанные данным объектом. Структуры, описывающие обработку и переадресацию сообщений, обычно выделяются в отдельный объект, называемый классом данного объекта. Сам объект называется экземпляром указанного класса.

Синтаксис и семантика

В синтаксисе чистых объектно-ориентированных языков все может быть записано в форме посылки сообщений объектам. Класс в объектно-ориентир ованных языках описывает структуру и функционирование множества объектов с подобными характеристиками, атрибутами и поведением. Объект принадлежит к некоторому классу и обладает своим собственным внутренним состоянием. Методы - функциональные свойст ва, которые можно активизировать.

В объектно-ориентированном программировании определяют три основных свойства:

Инкапсуляция. Это сокрытие информации и комбинирование данных и функций (методов) внутри объекта.

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

Большинство окружающих нас объектов относится к категориям, рассмотренным в книге [Шлеер , Меллор 1993]:

· Реальные объекты – абстракции предметов, существующих в физическом мире;

· Роли – абстракции цели или назначения человека, части оборудования или организации;

· Инциденты – абстракции чего-то произошедшего или случившегося;

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

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

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

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

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

Пример описания в некотором абстрактном Pascal -подобном объектно-ориентированном языке класса «точка», являющегося наследником класса «координаты» может выглядеть так:

Type TCoordinates = class (TObject )

x, y: integer;
Constructor Init (_x, _y: integer);
Function GetX : integer;
Function GetY : integer;
Procedure SetX (_x: integer);
Procedure SetY (_y: integer);
Procedure Move (dx , dy : integer);
Destructor Done; virtual;

Constructor Init();
x:= _x; y:= _y
end;
Function GetX : integer;
begin
GetX := x
end;
. . . . . . . . . . . . .
End;

TPoint = class (TCoordinates )
Color: integer;
Constructor Init (_x, _y, _Color: integer);
Function SetColor (_Color: integer);
Function GetColor : integer;

Constructor Init(_x, _y, _Color: integer);
Inherited Init(_x, _y);
Color:= _Color
end;
. . . . . . . . . . . . .

End ;

Если мы в дальнейшем хотим использовать экземпляры класса TPoint , их необходимо будет создать, вызвав метод-конструктор.

Var P1: Point;

P 1. Init (0,0 , 14); P 1. Move (+2, -2);

Для поддержки концепции ООР были разработаны специальные объектно-ориентирован-ные языки программирования. Все языки OOP можно разделить на три группы.

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

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

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

Литература

ISO/IEC 12207:1995 Information Technology – Software Life Cycle Processes.

[Вирт 1985] – Вирт Н. Алгоритмы + структуры данных = программы. – М.: Мир, 1985

[Дейкстра 1975] – Дейкстра Э. Заметки по структурному программированию // Дал У., Дейкстра Э., Хоар К. Структурное программирование. – М.: Мир, 1975

[Калинин, Мацкевич 1991] – Калинин А.Г., Мацкевич И.В. Универсальные языки программирования. Семантический подход. – М.: Радио и связь, 1991

[Лингер , Миллс, Уитт 1982] – Лингер Р., Миллс Х., Уитт Б. Теория и практика структурного программирования. – М.: Наука, 1990

[Майерс 1980] – Майерс Г. Надежность программного обеспечения. – М.: Мир, 1980

[Паронджанов 1999]- Параноджанов В.Д. Как улучшить работу ума. – М.: Радио и связь, 1999

[Пратт Т., 1979] - Пратт Т. Языки программирования: разработка и реализация. -М .:Мир , 1979

[Шлеер , Меллор 1993] - Шлеер С., Меллор С. Объектно-ориентированный анализ: моделирование мира в состояниях. – Киев: Диалектика, 1993.

  • Структурная
    • Разделение ответственности :
  • Шаблон: программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков . Предложена в 70-х годах XX века Э. Дейкстрой , разработана и дополнена Н. Виртом .

    В соответствии с данной методологией

    1. Любая программа представляет собой структуру, построенную из трёх типов базовых конструкций:
      • последовательное исполнение - однократное выполнение операций в том порядке, в котором они записаны в тексте программы;
      • ветвление - однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия;
      • цикл - многократное исполнение одной и той же операции до тех пор, пока выполняется некоторое заданное условие (условие продолжения цикла).
      В программе базовые конструкции могут быть вложены друг в друга произвольным образом, но никаких других средств управления последовательностью выполнения операций не предусматривается.
    2. Повторяющиеся фрагменты программы (либо не повторяющиеся, но представляющие собой логически целостные вычислительные блоки) могут оформляться в виде т. н. подпрограмм (процедур или функций). В этом случае в тексте основной программы, вместо помещённого в подпрограмму фрагмента, вставляется инструкция вызова подпрограммы . При выполнении такой инструкции выполняется вызванная подпрограмма, после чего исполнение программы продолжается с инструкции, следующей за командой вызова подпрограммы.
    3. Разработка программы ведётся пошагово, методом «сверху вниз».

    Сначала пишется текст основной программы, в котором, вместо каждого связного логического фрагмента текста, вставляется вызов подпрограммы, которая будет выполнять этот фрагмент. Вместо настоящих, работающих подпрограмм, в программу вставляются «заглушки», которые ничего не делают. Полученная программа проверяется и отлаживается. После того, как программист убедится, что подпрограммы вызываются в правильной последовательности (то есть общая структура программы верна), подпрограммы-заглушки последовательно заменяются на реально работающие, причём разработка каждой подпрограммы ведётся тем же методом, что и основной программы. Разработка заканчивается тогда, когда не останется ни одной «затычки», которая не была бы удалена. Такая последовательность гарантирует, что на каждом этапе разработки программист одновременно имеет дело с обозримым и понятным ему множеством фрагментов, и может быть уверен, что общая структура всех более высоких уровней программы верна. При сопровождении и внесении изменений в программу выясняется, в какие именно процедуры нужно внести изменения, и они вносятся, не затрагивая части программы, непосредственно не связанные с ними. Это позволяет гарантировать, что при внесении изменений и исправлении ошибок не выйдет из строя какая-то часть программы, находящаяся в данный момент вне зоны внимания программиста.

    Теорема о структурном программировании:

    Основная статья: Теорема Бома-Якопини

    Любую схему алгоритма можно представить в виде композиции вложенных блоков begin и end, условных операторов if, then, else, циклов с предусловием (while) и может быть дополнительных логических переменных (флагов).
    Эта теорема была сформулирована итальянскими математиками К. Бомом и Дж. Якопини в 1966 году и говорит нам о том, как можно избежать использования оператора перехода goto .

    История

    Методология структурного программирования появилась как следствие возрастания сложности решаемых на компьютерах задач, и соответственного усложнения программного обеспечения. В 70-е годы XX века объёмы и сложность программ достигли такого уровня, что «интуитивная» (неструктурированная, или «рефлекторная») разработка программ, которая была нормой в более раннее время, перестала удовлетворять потребностям практики. Программы становились слишком сложными, чтобы их можно было нормально сопровождать, поэтому потребовалась какая-то систематизация процесса разработки и структуры программ.

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

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

    Методология структурной разработки программного обеспечения была признана «самой сильной формализацией 70-х годов». После этого слово «структурный» стало модным в отрасли, и его начали использовать везде, где надо и где не надо. Появились работы по «структурному проектированию», «структурному тестированию», «структурному дизайну» и так далее. В общем, произошло примерно то же самое, что происходило в 90-х годах и происходит в настоящее время с терминами «объектный», «объектно-ориентированный» и «электронный».

    Перечислим некоторые достоинства структурного программирования:

    1. Структурное программирование позволяет значительно сократить число вариантов построения программы по одной и той же спецификации, что значительно снижает сложность программы и, что ещё важнее, облегчает понимание её другими разработчиками.
    2. В структурированных программах логически связанные операторы находятся визуально ближе, а слабо связанные - дальше, что позволяет обходиться без блок-схем и других графических форм изображения алгоритмов (по сути, сама программа является собственной блок-схемой).
    3. Сильно упрощается процесс тестирования и отладки структурированных программ.

    См. также

    Ссылки


    Wikimedia Foundation . 2010 .

    • Махаджанапады
    • Camel

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

      Структурное программирование - методология и технология разработки программных комплексов, основанная на принципах: программирования сверху вниз; модульного программирования. При этом логика алгоритма и программы должны использовать три основные структуры: последовательное… … Финансовый словарь

      структурное программирование - struktūrinis programavimas statusas T sritis automatika atitikmenys: angl. structured coding; structured programming vok. strukturelle Programmierung, f rus. структурированное программирование, n; структурное программирование, n pranc.… … Automatikos terminų žodynas

      Структурное программирование - 46. Структурное программирование Structured programming Источник: ГОСТ 19781 90: Обеспечение систем обработки информации программное. Термины и определения … Словарь-справочник терминов нормативно-технической документации

      Программирование - Эта статья должна быть полностью переписана. На странице обсуждения могут быть пояснения. У этого термина существуют и другие значения, см. Программи … Википедия

      ПРОГРАММИРОВАНИЕ - 1) процесс составления программы, плана действий. 2) Раздел информатики, изучающий методы и приёмы составления программ. С долей условности П. как дисциплина разделяется на: теоретическое, изучающее матем. абстракции программ (как объектов с… … Физическая энциклопедия

      Программирование основанное на прототипах - Прототипное программирование стиль объектно ориентированного программирования, при котором отсутствует понятие класса, а повторное использование (наследование) производится путём клонирования существующего экземпляра объекта прототипа.… … Википедия

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

      Компьютерное программирование - Разработка программного обеспечения Процесс разработки ПО Шаги процесса Анализ | Проектирование | Реализация | Тестирование | Внедрение | Сопровождение Модели / методы Agile | Cleanroom | Итеративная | Scrum | RUP | MSF | Спиральная | … Википедия

      Неструктурированное программирование - Структурное программирование методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 70 х годах XX века Э. Дейкстрой, разработана и дополнена Н. Виртом. В … Википедия

      Компонентно-ориентированное программирование - Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

    Книги

    • Дисциплина программирования , Дейкстра Э. , Книга написана одним из крупнейших зарубежных специалистов в области программирования, известным советскому читателю по переводам его книг на русский язык (например, «Структурное… Категория: Математика и естественные науки Серия: Издатель: ЁЁ Медиа , Купить за 2177 руб
    • Программирование. Основы алгоритмизации и программирования. Учебник , А. Н. Пылькин , Б. Г. Трусов , Н. И. Парфилова , Учебник создан в соответствии с Федеральным государственным образовательным стандартом по направлению подготовки 230100 `Информатика и вычислительная техника` (квалификация `бакалавр`).… Категория:

    Структурное программирование – это проектирование, написание и тестирование программы в соответствии с жестким соблюдением определенных правил.

    Основная цель структурного программирования – повышение производительности программистов. Другими целями являются:

    – избавиться от плохой структуры программы;

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

    Структурное программирование (или метод пошаговой детализации) включает:

    1. Метод нисходящего проектирования. Его еще называют методом «сверху вниз» или «от общего к частному». Он предполагает разбиение задачи на несколько более простых частей или подзадач. Их выделяют таким образом, чтобы проектирование подзадач было независимым. При этом составляют план решения всей задачи, пунктами которого и являются выделенные части. План записывают графически в виде функциональной схемы (схемы иерархии, подчинения), где определяют головную и подчиненные подзадачи и связи между ними, т.е. интерфейс. Здесь же устанавливается, какие начальные данные (или значения) получает каждая подзадача для правильного функционирования и какие результаты она выдает. Затем производят детализацию каждой подзадачи. Число шагов детализации может быть произвольным. Детализацию продолжают до тех пор, пока не станет ясно, как программировать данный фрагмент алгоритма.

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

    3. Сквозной структурный контроль. Он представляет собой регулярные проверки и согласования результатов работы исполнителей - программистов различных структур. Его необходимость определяется желанием разработчиков снизить стоимость разрабатываемых программ. Обязательным условием этого является раннее обнаружение и исправление возникающих ошибок и не состыковок.

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



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

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

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


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

    Функциональный блок алгоритма относится к простому типу блоков.

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

    1) выполняется каждый блок;

    2) каждый блок выполняется не более одного раза.

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

    Поток управления, в котором выполняются оба указанных свойства, называется линейным.


    Очевидно, что несколько блоков, связанных линейным потоком, могут быть объединены в один функциональный блок.

    2. Ветвящийся поток управления. В этом типе выполняется свойство (2), а свойство (1) не выполняется.

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

    3. Циклический поток управления. Он организует многократное повторение функционального блока, пока логическое условие его выполнения остается истинным.

    В данном типе потока управления выполняется свойство (1), но не выполняется свойство (2).


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

    Структурные алгоритмы обладают рядом преимуществ по сравнению с неструктурными алгоритмами:

    1. понятность и простота восприятия алгоритма;

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

    3. модифицируемость.

    Структурная теорема : любой алгоритм может быть сведен к структурному алгоритму.

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

    Исходя из структурного подхода к разработке алгоритма, типовыми этапами этого процесса являются:

    1. Описание общего замысла алгоритма;

    2. Формализация задачи;

    3. Разработка обобщенной схемы алгоритма;

    4. Разработка отдельных блоков алгоритма;

    5. Стыковка блоков;

    6. Определение возможности использования стандартных блоков;

    7. Разработка блоков логического контроля;

    8. Оптимизация схемы алгоритма;

    9. Уточнение параметров;

    10. Оценка машинного ресурса.

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

    Текст программы должен быть таким, чтобы его можно было читать «сверху - вниз». Неограниченное использование операторов безусловного перехода (GO TO ) нарушает это условие, поэтому структурное программирование часто называют программирова­нием без GO ТО.

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

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

    Любую программу можно синтезировать на основе элементар­ных базовых конструкций трех типов:

    1. Простая последовательность. 2. Условия (альтернативы).

    3. Повторение (циклы, итерации). Возможны один из двух или оба вида:

    Делать «пока» Делать «пока не»

    4. Можно добавить четвертую конструкцию - выбор (пе­реключатель).

    Блоки определяются рекурсивно: прямоугольники изобра­жают вложенные строительные блоки, используемые вместо прямоугольника.

    Перечисленные элементарные конструкции, например, в языке Паскаль реализованы так:

    Условный оператор IF лог. выр . THEN оператор 1 ELSE оператор2 ;

    IF лог. выражение THEN оператор ;

    Повторение (циклы, итерации)

    а) Делать «пока» WHILE условие продолжения DO оператор ;

    б) Делать «пока не» REPEAT оператор UNTIL условие завершения ;

    в) Цикл с перебором FOR К:=В1 ТО В2 DO оператор ;

    FOR K:=B2 DOWNTO B1 DO оператор ;

    Выбор (переключатель) CASE условие OF

    N1, ... Nk : оператор 1 ;

    Ni , ... Nm : оператор п ;

    END ;

    В языке FoxBASE эти конструкции реализованы в виде:

    Условный оператор IF лог. выражение

    операторы1

    [ ELSE

    операторы2 ]

    ENDIF

    Цикл DO WHILE выражение

    операторы

    ENDDO

    Выбор (переключатель) DO CASE

    CASE лог . выражение 1

    операторы

    CASE лог. выражение2

    Операторы

    CASE лог. Выражение п

    Операторы

    ENDCASE

    Каждая структура характеризуется единственной точкой пере­дачи управ­ле­ния в структуру (единственный вход) и единствен­ной точкой выхода из структуры.

    Эти конструкции имеют систематизирующее и дисципли­нирующее значение. Простота исходных конструкций структур­ного программирования предотвращает появление сложных ин­формационных связей и запуганных передач управления.

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

    Структурность программы зависит от используемого языка програм­ми­ро­ва­ния. Современные программные средства раз­работки программ яв­ляются «наи­луч­шими» языками струк­турного программирования. Из рас­простра­ненных языков прог­раммирования самыми подходящими считаются Паскаль, Basic , FoxBASE . Структурное программирование, например, на языке Ассемблер почти невозможно. Сам факт использования языка Ассемблера указывает на то, что программа написана в основном в терми­нах машинного языка.

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

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

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

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

    ФГБОУ ВО «Мордовский государственный

    педагогический институт имени М.Е. евсевьева»

    Физико-математический факультет

    Кафедра информатики и вычислительной техники

    РЕФЕРАТ

    «Принципы структурного программирования. Основные алгоритмические структуры и их суперпозиции»

    Выполнила: студентка гр. МДМ-212

    Багданова Яна

    Саранск 2016

    Введение

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

    Исходя из этих проблем, ведущими программистами 70-х годов (Дейкстра , Вирт , Дал , Xoap , Йордан , Константин , Майерс и др.) были разработаны строгие правила ведения проектов, которые получили название структурной методологии .

    Важным этапом в становлении этого подхода стали международные конференции по программированию, проведенные в 1968-69 годах. На второй из них Эдсгер Дейкстра впервые использовал термин « структурное программирование » и предложил принципиально новый способ создания программ. Он рассматривал программу как совокупность иерархических абстрактных уровней, которые позволяли:

      четко структурировать программу, что улучшило ее понимание программистами;

      выполнять доказательства ее корректности и тем самым повышать надежность функционирования программы;

      сокращать сроки разработки программ.

    Еще одним толчком к изменению способа программистского мышления стало опубликованное письмо Дейкстры редактору одного из научных издательств, которое было озаглавлено « Оператор GOTO нужно считать вредным ». Это письмо вызвало острую полемику среди программистов того времени, но в итоге победило все-таки структурное мышление, которое, кроме Дейкстры , активно поддерживали профессор Цюрихского технического университета Вирт и профессор Оксфордского университета Xoap . Одним из результатов полемики было доказательство того, что любая программа может быть написана, используя только простую последовательность операторов, итеративную конструкцию типа while ( пока ) и конструкцию выбора case ( выбор ), а оператор goto ( перейти к ) не является необходимой управляющей конструкцией в структурном программировании. К сожалению, споры об операторе goto имели один отрицательный «побочный эффект» - довольно часто программирование без goto стало отождествляться со всем структурным программированием. Однако цели структурного программирования намного глобальнее и серьезнее.

    1. ОСНОВЫ ТЕХНОЛОГИИ СТРУКТУРНОГО ПРОГРАММИРОВАНИЯ

    Структурное программирование - методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 70-х годах XX в. Э.Дейкстрой, разработана и дополнена Н.Виртом (рис. 1).

    Эдсгер Вибе Дейкстра (1930 – 2002) - нидерландский учёный, идеи которого оказали влияние на развитие компьютерной индустрии. Известен как создатель алгоритма поиска кратчайшего пути на графе, один из основателей структурного программирования. В 1972 г. стал лауреатом премии Тьюринга.

    Никлаус Вирт (1934) - швейцарский учёный, специалист в области информатики, один из известнейших теоретиков в области разработки языков программирования, профессор компьютерных наук, лауреат премии Тьюринга 1984 г. Ведущий разработчик языков программирования Паскаль, Модула-2, Оберон.

    Рис. 1. Пионеры структурного программирования – Э.Дейкстра и Н.Вирт.

    Методология структурного программирования появилась как следствие возрастания сложности решаемых на компьютерах задач, и соответственного усложнения программного обеспечения: в 70-е годы XX в. объёмы и сложность программ достигли такого уровня, что «интуитивная» (неструктурированная) разработка программ, которая была нормой в более раннее время, перестала удовлетворять потребностям практики. Программы становились слишком сложными, чтобы их можно было нормально сопровождать, поэтому потребовалась какая-то систематизация процесса разработки и структуры программ.

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

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

    Типичными методами структурного программирования являются:

      нисходящее проектирование (проектирование сверху вниз);

      модульное (процедурное) программирование ;

      структурное кодирование .

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

    1. Любая программа представляет собой структуру, построенную из трёх типов базовых конструкций:

      последовательное исполнение - однократное выполнение операций в том порядке, в котором они записаны в тексте программы;

      ветвление - однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия;

      цикл - многократное исполнение одной и той же операции до тех пор, пока выполняется некоторое заданное условие (условие продолжения цикла).

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

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

    3. Разработка программы ведётся пошагово, методом «сверху вниз».

    Сначала пишется текст основной программы, в котором, вместо каждого связного логического фрагмента текста, вставляется вызов подпрограммы, которая будет выполнять этот фрагмент. Вместо настоящих, работающих подпрограмм, в программу вставляются « заглушки », которые ничего не делают. Полученная программа проверяется и отлаживается. После того, как программист убедится, что подпрограммы вызываются в правильной последовательности (т.е. общая структура программы верна), подпрограммы-заглушки последовательно заменяются на реально работающие, причём разработка каждой подпрограммы ведётся тем же методом, что и основной программы. Разработка заканчивается тогда, когда не останется ни одной «заглушки», которая не была бы удалена. Такая последовательность гарантирует, что на каждом этапе разработки программист одновременно имеет дело с обозримым и понятным ему множеством фрагментов, и может быть уверен, что общая структура всех более высоких уровней программы верна. При сопровождении и внесении изменений в программу выясняется, в какие именно процедуры нужно внести изменения, и они вносятся, не затрагивая части программы, непосредственно не связанные с ними. Это позволяет гарантировать, что при внесении изменений и исправлении ошибок не выйдет из строя какая-то часть программы, находящаяся в данный момент вне зоны внимания программиста.

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

    Методология структурной разработки программного обеспечения была признана «самой сильной формализацией 70-х годов». После этого слово «структурный» стало модным в отрасли, и его начали использовать везде, где надо и где не надо. Появились работы по «структурному проектированию», «структурному тестированию», «структурному дизайну» и т.д.

    К достоинствам структурного программирования можно отнести следующее:

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

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

    3. Сильно упрощается процесс тестирования и отладки структурированных программ.

    Рассмотрим более подробно основные методы структурного программирования.

    1.1. Цели и принципы структурного программирования

    Целями структурного программирования являются:

      Обеспечение дисциплины программирования в процессе создания программных комплексов .

      Улучшение читабельность программы . Читабельность улучшается, если придерживаться следующих правил:

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

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

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

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

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

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

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

    Таблица 1. Принципы структурного программирования

    Принцип

    Пояснение

    Абстракция

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

    Формальность

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

    «Разделяй и властвуй»

    Разделение программы на отдельные фрагменты (модули), которые просты по управлению и допускают независимую отладку и тестирование.

    Иерархическое упорядочение

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

    1.2. Нисходящее проектирование

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

    Спецификация задачи является ее первичным проектом. От неё мы движемся к программе, постепенно уточняя описание.

    Постепенное уточнение проекта называется методом проектирования сверху вниз ( пошаговой детализации или нисходящего проектирования ).

    Пример 1. В качестве примера рассмотрим проект одевания ребенка.

    Решение:

    1. Первичная цель :

    Одеть.

    2. Конкретизация цели на первом шаге :

    Одеть нижнюю половину.

    Одеть верхнюю половину.

    2.1. Нижнюю половину можно одеть в два этапа:

    Надеть брюки.

    Надеть носки и ботинки.

    2.2. Верхнюю половину можно также одеть в два этапа:

    Надеть рубашку.

    Надеть куртку.

    3. Окончательный проект выглядит так:

    Надеть брюки.

    Надеть носки.

    Надеть ботинки.

    Надеть рубашку.

    Надеть куртку.

    Метод нисходящего проектирования предполагает последовательное разложение общей функции обработки данных на простые функциональные элементы («сверху-вниз»). В результате строится иерархическая схема – функциональная структура алгоритма ( ФСА ), отражающая состав и взаимоподчиненность отдельных функций (рис. 2).

    Приложение 1

    Приложение n

    Функция 1

    Функция 2

    Функция m

    Подф-ция 11

    Подф-ция 1 k

    Подф-ция m 1

    Подф-ция m 2

    Подф-ция mp

    Цель 1

    Подцель 11

    Подцель 1 s

    Цель 2

    Подцель 2 1

    Подцель 2 q

    Рис. 2. Функциональная структура приложения

    Последовательность действий по разработке ФСА приложения следующая:

      определяются цели автоматизации предметной области и их иерархия (цель-подцель);

      устанавливается состав приложений (задач обработки), обеспечивающих реализацию поставленных целей;

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

      определяются необходимые для решения задач функции обработки данных ;

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

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

    1.3. Модульное программирование

    Модульное программирование является естественным следствием проектирования сверху вниз и заключается в том, что программа разбивается на части – модули , разрабатываемые по отдельности.

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

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

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

    Некоторые программные продукты используют модули из готовых библиотек стандартных подпрограмм, процедур, функций, объектов, методов обработки данных.

    Среди множества модулей различают:

      головной модуль – управляет запуском программного продукта (существует в единственном числе);

      управляющий модуль – обеспечивает вызов других модулей на обработку;

      рабочие модули – выполняют функции обработки;

      сервисные модули и библиотеки , утилиты – реализуют обслуживающие функции.

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

    Каждый модуль может оформляться как самостоятельно хранимый файл; для функционирования программного продукта необходимо наличие программных модулей в полном составе.

    Модуль должен обладать следующими свойствами :

      один вход и один выход – на входе программный модуль получает определенный набор исходных данных, выполняет содержательную обработку и возвращает один набор результатных данных, т.е. реализуется стандартный принцип IPO ( Input–Process–Output вход-процесс-выход );

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

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

      слабые информационные связи с другими программными модулями – обмен информацией между модулями должен быть по возможности минимизирован;

      обозримый по размеру и сложности программный код .

    Модули содержат:

      определение доступных для обработки данных;

      операции обработки данных;

      схемы взаимосвязи с другими модулями.

    Каждый модуль состоит из спецификации и тела . Спецификации определяют правила использования модуля, а тело – способ реализации процесса обработки.

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

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

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

      принятие основных решений в алгоритме выносится на максимально «высокий» по иерархии уровень;

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

    В результате дальнейшей детализации алгоритма создается функционально-модульная схема ( ФМС ) алгоритма приложения, являющаяся основой для программирования (рис. 2).

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

    Второй уровень иерархии программы

    Первый уровень иерархии программы

    Головной модуль

    (программа-сервер)

    Модуль управления 1

    (Управл. прогр. 1)

    Модуль управления n

    (Управл. прогр. n)

    Модуль 1A

    (подпрогр. 1А)

    Модуль 1В

    (подпрогр. 1В)

    Модуль 1W

    (подпрогр. 1 W )

    Модуль 0A

    (подпрогр. 0А)

    Модуль 0B

    (подпрогр. 0B)

    Модуль nA

    (подпрогр. nА)

    Модуль nB

    (подпрогр. nB)

    Модуль nW

    (подпрогр. nW)

    Третий уровень иерархии программы

    Рис. 3. Функционально-модульная структура алгоритма приложения

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

      точки (момент, условие) начала диалога;

      инициатор диалога – человек или программный продукт;

      параметры и содержание диалога – сообщения, состав и структура меню, экранные формы и т.п.;

      реакция программного продукта на завершение диалога.

    Для создания диалоговых процессов и интерфейса конечного пользователя наиболее подходят объектно-ориентированные инструментальные средства разработки программ .

    1.4. Структурное кодирование

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

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

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

    Свойство структурности операторов состоит в том, что каждый оператор имеет один вход и один выход . Программа, построенная из структурных операторов, называется структурированной .

    Фундаментом структурного программирования является теорема о структурировании , сформулированная итальянскими математиками К.Бомом и Дж.Якопини в 1966 г.

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

      следования (begin-end начало-конец ),

      ветвления (if - then - else если-то-иначе ),

      циклов с предусловием (while пока ).

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

    На практике данная теорема позволяет избежать использования операторов перехода goto , что делает алгоритмы и программы наглядными и легко понимаемыми.

    Виды основных управляющих структур алгоритма приведены на рис. 4.

    1. Структура типа « следование » (рис. 4, а ) – образуется последовательностью действий, S 1, S 2, …, Sn , следующих одно за другим:

    выполнить S 1;

    выполнить S 2;

    выполнить Sn .

    В линейном вычислительном процессе все операции выполняются последовательно в порядке их записи. Типовым примером такого процесса является стандартная вычислительная схема, состоящая из трех этапов:

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

      вычисление по формулам;

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

    В языке Pascal такая структура заключается в операторные скобки Begin ... End :

    Begin

    S 1;

    S 2;

    ...

    Sn ;

    End

    Рис. 4. Базовые алгоритмические структуры:

    а) следование (Begin End ); б) ветвление (If Then Else ); в) цикл с предусловием (While Do )

    2. Структура типа « ветвление » (ЕСЛИ – ТО – ИНАЧЕ ) (рис. 4, б ) – обеспечивает в зависимости от результата проверки условия Р , принимающего одно из двух логических значении Да (True ) или Нет (False ), выбор одного из альтернативных путей работы алгоритма:

    если Р

    то выполнить S 1

    иначе выполнить S 2 .

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

    В языке Pascal

    If P

    Then S 1

    Else S 2;

    3. Структура типа « цикл с предусловием » (рис. 4, в ) – обеспечивает многократное выполнение действия S в зависимости от того, какое значение принимает логическое условие Р :

    до тех пор пока Р

    выполнять S .

    Выполнение цикла прекращается, когда условие Р не выполняется.

    В языке Pascal такая структура имеет следующий формат:

    While P Do

    S ;

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

    4. Структура типа « сокращенное ветвление » (ЕСЛИ – ТО ) (рис. 5, а ) – если результат проверки условия Р принимает значение Да (True ), то выполняется действие S ; в противном случае это действие пропускается и управление передается следующей структуре:

    если Р

    то выполнить S 1 .

    В языке Pascal такая структура имеет следующий формат:

    If P

    Then S ;

    5 . Структура типа « выбор – иначе » (рис. 5, б ) являются расширенным вариантом структуры типа ЕСЛИ – ТО – ИНАЧЕ . Здесь проверяемое условие Р может принимать не два логических значения, а несколько порядковых значений, например, 1, 2, …, n . Если Р = i , то будет выполняться действие Si . Если же значение Р будет выходить из диапазона допустимых значений, то выполняется действие S (в укороченном варианте « выбор » никакого действия не производится и управление передается к следующей структуре. В языке Pascal такая структура имеет следующий формат:

    Case P Of

    1: S1;

    2: S2;

    n: Sn

    Else S

    End;

    Рис. 5. Дополнительные элементарные алгоритмические структуры:

    а) сокращенное ветвление (If Then ); б) выбор – иначе (Case Of Else );
    в) цикл с постусловием (Repeat Until ); г) цикл с параметром (For To ( Downto ) – Do )

    6. Структура типа « цикл с постусловием » (рис. 5, в ) – обеспечивает многократное выполнение действия S до тех пор, пока не выполняется условие Р .

    В языке Pascal такая структура имеет следующий формат:

    Repeat

    S

    Until P ;

    7. Структура типа « цикл с параметром » (рис. 5, г ) – обеспечивает заранее определенное многократное выполнение действия S . При этом здесь последовательно выполняются следующие типовые операции:

      задание начального значения используемого параметра цикла (например, если переменной цикла является i , то ей присваивается значение i 1, т.е. i :=i 1);

      выполнение действий S , предусмотренных в теле цикла;

      изменение параметра цикла, который обеспечивает вычисление результата с новыми начальными данными (например, если параметр цикла i изменяется с шагом i 3, i :=i i 3);

      проверка текущего значения параметра цикла с заданным конечным значением (i <=i 2);

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

    В языке Pascal такая структура имеет следующий формат:

    For Переменная := i 1 To (Downto) i 3 Do

    S ;

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

    Структурные операторы обычно применяются уже на ранних стадиях нисходящего проектирования программы.

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

    ВЫВОДЫ

      Структурное программирование - методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 70-х годах XX в. Э.Дейкстрой, разработана и дополнена Н.Виртом. Типичными методами структурного программирования являются: нисходящее проектирование (проектирование сверху вниз); модульное (процедурное) программирование; структурное кодирование.

      Целями структурного программирования являются: обеспечение дисциплины программирования, повышение эффективности и надежности программ, уменьшение времени и стоимости программной разработки. Основные принципы структурного программирования: абстракция, формальность, «разделяй и властвуй», иерархическое упорядочение.

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

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

      Фундаментом структурного программирования является теорема о структурировании, сформулированная итальянскими математиками К.Бомом и Дж.Якопини в 1966 г. Теорема устанавливает, что как бы сложна ни была задача, схему алгоритм ее решения (и, соответственно, программу) всегда можно представить в виде композиции трех типов вложенных блоков: следования (begin-end – начало-конец), ветвления (if-then-else – если-то-иначе), циклов с предусловием (while – пока).

    * Э.Дейкстра дал следующее определение: «Структурное программирование – это дисциплина, которую программист навязывает сам себе ».

    В продолжение темы:
    D-link

    В наш век, когда развитая «мировая паутина» опутывает планету буквально несколькими слоями, локальные сети, казалось бы, отошли на второе место, прочно заняв нишу единения...

    Новые статьи
    /
    Популярные