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

В структурном программировании используются только простые логические структуры Якопини 1 доказал, что любая- программа может быть написана с использованием только трех структур:

1) последовательной, в которой, команды или программы выполняются последовательно в ioM порядке, в котором оии записаны;

2) условной типа IF—THEN—ELSE, т. е. IF A THEN P1 ELSE P2. где A — логическое выражение, a Pt» P* — программы, составленные из трех канонических структур. Если выражение А истинно, ЭВМ выполняет программу Pv Есл* А ложно,. ЭВМ выполняет программу KV Программе Р2 может быть опущена если ЭВМ не должна выполнять никаких действий в том случае, когда выражение А ложно.
 

Пример. Используется полная форма условного оператора с THEN и ELSE.

IF X != OTHEN Y = 1/X ELSE Y = 0.

Эта конструкция обеспечивает предотвращение деления на нуль и опре* деление значения Y в том случае, когда X равен нулю.

Пример. Сокращенная форма оператора без ELSE. IF CENTS  >= 60 THEN DOLLARS = DOLLARS + 1- С помощью этого онератора осуществляется округление переменной DOLLARS до ближайшего дол-лара. Если CENTS <50, никаких действий выполнять не нужно;

3) циклической типа DO — WHILE, т. е. DO Р WHILE А (выполнять Р, пока А), где А—логическое выражение, Р—программа, со-стоящая только из допустимых структурных элементов. Электронно-вычислительная машина проверяет справедливость утверждения А и выполняет программу Р, если А истинно, а затем снова возвращается к проверке А и т. д. Другими словами, ЭВМ выполняет программу Р, пока выражение А остается истинным.

Пример.

INDEX = 1

DO WHILE INDEX < MAX

BLK1 (INDEX) = В1Ж2 (INDEX)

INDEX * INDEX + 1 END

Приведенный оператор пересылает группу элементов, ■число которых задано переменной МАХ, из массива 1 (BLKJ) в массив 2 (BLK2).

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

Каждый такой структурный элемент имеет один вход и один выход'. Если при выполнении программы Р4 (рис. 6.6, а) возникнет ошибка, будет точно известно, как ЭВМ попала в эту точку. Если бы программа была неструктурированной (рис. 6.7), то можно было бы предположить, что ошибка возникла в любой из ветвей, ведущих в Ра. Кроме того, любая корреетирошеа может повлиять на выполнение других частей про-граммы. Очевидно, ситуация будет еще более запутанной, если программа имеет к тому же более одного выхода.

Типичный пример тех сложностей, которые возникают при отладке неструктурированных программ, можно проиллюстрировать на следующем фрагменте программы на языке ФОРТРАН

40 COUNT = 1

NUNIT - XLENG/SCALE

Предположим, что при вычислении переменкой NUNIT ЭВМ пыталась выполнить операцию деления на нуль. Где возникла ошибка? Сначала необходимо обнаружить все операторы, из которых управление передается оператору 40, а это может потребовать просмотра всей программы или таблицы перекрестных ссылок Затем необходимо выяснить, выполнение какого из операторов привело к ошибке.

Внесение исправлений в фрагмент программы не должно влиять на другие части программы, которые также включают в себя измененный фрагмент. Структурированные программы позволяют упростить работу по тестированию, отладке и сопровождению в процессе разработки ПО. Наибольшие сложности в программах на языке ФОРТРАН возникают в результате использования операторов GOTO и 1F, которые настолько усложняют структуру программы, что программисту бывает трудно понять, каким образом программа оказывается в некоторой точке. Многие сторонники структурного программирования твердо убеждены, что для получения структурированных программ надо обязательно отказаться от использования оператора GOTO (безусловный переход). Основной смысл структурного программирования состоит в том, что более простые схемы вычислительного процесса позволяют получить более четкие, более надежные и просто тестируемые программы.

До сих пор результаты использования методов структурного программирования в различных условиях были обнадеживающими. В настоящее время большинство крупных программных проектов реализуется с использованием подобных методов, имеющих иногда некоторые особенности. Сообщалось о том, что производительность труда программистов удавалось повысить от 50 до 100%, хотя в большинстве случаев для повышения производительности труда использовалось сразу несколько методов и отсутствовали измерительные эксперименты с хорошо продуманным контролем.

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

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

Сложность состоит в том, что мало кто из проектировщиков систем использует языки, допускающие возможность структурного программирования. Языки высокого уровня, основанные на ПЛ/1 (например, ПЛ/М фирмы Intel и МП Л фирмы Motorola), имеют необходимые средства структурирования и могут использоваться для составления структурированных программ. В статье Поппера1 было сообщение о появлении структурного макроассемблера. Однако сейчас большинство программ пишется с помощью обычных ассемблеров, подобных ассемблерам, описанным в гл. 4. Таким образом, структурное программирование следует использовать на этапе проектирования программы, а затем преобразовывать структурированную программу в ассемблерную примерно так же, как это делается при ручном преобразовании ассемблерной программы в машинный код. Поскольку кодирование обычно занимает незначительную долю времени, затрачиваемого на программирование, введение еще одного этапа проектирования может оказаться полезным. Структурированные программы часто оказываются более медленными и требуют больше памяти, чем неструктурированные. Однако уже отмечалось, что время работы программы и затраты памяти не так существенны при разработке микропроцессорных систем, как время, затрачиваемое на создание программ. Использование методов структурного программирования может существенно уменьшить общие сроки разработки программы.

; Установить указатель на первую позицию строки - и прочитать ; первый' бимвол с клавиатуры

CHARACTER POINTER = 1 READ INPUT

; Анализировать символы до обнаружения символа «возврат ка-; ретки»

DO WHILE INPUT# CARRIAGE RETURN;

; Если входной символ — пробел и не достигнут конец строки,

; увеличить указатель на единицу

IF INPUT « SPACE THEN

IF CHARACTER POINTER ф 80 THEN

CHARACTER POINTER = CHARACTER POINTER + 1 ; Если видной симвбл — знак возврата и он не находится в начале ; строки, увеличить указатель на единицу

ELSE IF INPUT = BACKSPACE THEN IF CHARACTER POINTER Ф 1 THEN

CHARACTER POINTER = CHARACTER POINTER + 1

»

; Стёреть символ, заменив его пробелом

ELSE IF INPUT -= DELETE THEN

CHARACTER (CHARACTER POINTER) - SPACE

; Заменить на введенный символ

ELSE

CHARACTER (CHARACTER POINTER) == INPUT IF CHARACTER POINTER Ф 80 THEN

CHARACTER POINTER = CHARACTER POINTER + 1

; Прочитать следующий входной символ ; READ INPUT END

Типичным примером применения методов структурного программирования является разработка простой программы-редактора. Программа позволяет осуществлять перемещение влево и вправо по строке (на экране дисплея или телетайпа), стирание или замену символов и завершает процесс редактирования при нажатии на клавищу «возврат каретки» (ВК). На рис. 6.8 показана структурированная программа, выполняющая функции редактора (в этом примере комментарии помечаются точкой с запятой, а для выделения начала и конца структурных компонентов используются абзацные отступы). В приведенном примере структурированного редактора отсутствуют операторы безусловного перехода (операторы GOTO). Главный цикл, выполняемый до обнаружения символа ВК (тело цикла не будет выполнено ни разу, если первым встреченным символом будем ВК), реализован с помощью структурного оператора DO-WHILE. Внутри цикла имеются конструкции IF-THEN-ELSE.

Для выделения этих структур на различных уровнях сделаны соответствующие абзацные отступы. Если не предусмотреть такого выделения, возникают большие затруднения при определении того, какие ELSE каким THEN соответстсвуют и какие ELSE опущены. Некоторые авторы для обозначения конца программного блока, включен* о-го в оператор IF, используют необязательный ELSE, ENDIF или FI (слово IF в обратном порядке). Заметим, что один и тот же структурированный вариант проекта программы может использоваться для того, чтобы переписать Программу на другом языке или для другой ЭВМ. Структурное программирование требует соблюдения программистом определенной дисциплины составления программ, но существенно сокращает время, необходимое для разработки.



Бейдж с окошком полноцветная печать на бейджах.