Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практичне заняття № 4 МЗКІТ (рус, дороб) (10 ТП).DOCX
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
6.04 Mб
Скачать

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

Структурное программирование — методология программирования, базирующаяся на системном подходе к анализу, проектированию и реализации программного обеспечения. Эта методология зародилась в начале 70-х годов и оказалась настолько жизнеспособной, что и до сих пор является основной в большом количестве проектов. Основу этой технологии составляют следующие положения:

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

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

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

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

Конечно, язык ассемблера, в силу его специфики, довольно ограниченно реализует данные положения. В частности, это касается управляющих операторов цикла, условных операторов и операторов выбора. Эти операторы являются встроенными в язык высокого уровня, но в языке ассемблера их попросту нет. Были попытки разработать различные надстройки для языка ассемблера, реализующие эти управляющие операторы, но широкого распространения они не получили. Мне кажется, что это и не нужно, так как реализуемые на языке ассемблера программы решают специфичные системные задачи. Тогда возникает вопрос — а вообще совместимы ли структурное программирование и ассемблер? Ответ положительный, особенно в том случае, если задача поддается разбиению на более мелкие подзадачи. Тогда реализацию этих подзадач можно осуществить с использованием макрокоманд и процедур. Эти механизмы полностью подходят для реализации так называемого модульного программирования, которое является частью структурного подхода. Рассмотрим, что представляет собой модульное программирование.

Концепция модульного программирования

Так же как и для структурной технологии программирования, концепцию модульного программирования можно сформулировать в виде нескольких понятий и положений:

  • Функциональная декомпозиция задачи — разбиение большой задачи на ряд более мелких, функционально самостоятельных подзадач — модулей. Моду¬ли связаны между собой только по входным и выходным данным.

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

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

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

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

  • назначение модуля;

  • особенности функционирования;

  • описание входных аргументов;

  • описание выходных аргументов;

  • использование внешних модулей и переменных;

  • сведения о разработчике для защиты авторских прав.

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

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

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

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

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

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

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

  • В качестве основных информационных связей можно выделить следующие:

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

  • Унифицированную передачу аргументов при вызове модуля. Эту унифика¬цию можно представлять двояко: на уровне пользователя и на уровне конкретного компилятора.

  • Унифицированную передачу аргументов при возврате управления из модуля.

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

  • макросредства;

  • процедуры;

  • средства компилятора ассемблера в форме директив организации оперативной памяти и ее сегментации.

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