Структурное программирование. Технология структурного программирования Структурное программирование си

Становление и развитие структурного программирования связано с именем Эдсгера Дейкстры .

Принцип 1 . Следует отказаться от использования оператора безусловного перехода GoTo.

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

  • Последовательность - однократное выполнение операций в том порядке, в котором они записаны в тексте программы. Бертран Мейер поясняет: «Последовательное соединение: используйте выход одного элемента как вход к другому, подобно тому, как электрики соединяют выход сопротивления со входом конденсатора» .
  • Ветвление - однократное выполнение одной из двух или более операций, в зависимости от выполнения заданного условия.
  • Цикл - многократное исполнение одной и той же операции до тех пор, пока выполняется заданное условие (условие продолжения цикла).

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

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

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

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

Принцип 5 . Каждую логически законченную группу инструкций следует оформить как блок (block). Блоки являются основой структурного программирования.

Блок - это логически сгруппированная часть исходного кода, например, набор инструкций, записанных подряд в исходном коде программы. Понятие блок означает, что к блоку инструкций следует обращаться как к единой инструкции. Блоки служат для ограничения области видимости переменных и функций. Блоки могут быть пустыми или вложенными один в другой. Границы блока строго определены. Например, в if-инструкции блок ограничен кодом BEGIN..END (в языке Паскаль) или фигурными скобками {...} (в языке C) или отступами (в языке Питон).

Принцип 6 . Все перечисленные конструкции должны иметь один вход и один выход.

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

Принцип 7 . Разработка программы ведётся пошагово, методом «сверху вниз» (top-down method) .

Введение

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

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

История

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

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

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

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

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

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

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

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

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

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

Например, Хоор определяет структурное программирование как "систематическое использование абстракции для управления массой деталей и способ документирования, который помогает проектировать программу".

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

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

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

Структурное программирование улучшает ясность и читабельность программ.

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

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

Наконец, структурное программирование призвано улучшить эффективность программ.

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

Основные критерии оценки качества программы для ЭВМ.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

6. Простота и эффективность. Программа должна быть просто организована.

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

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

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

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

Для студентов специальности
Т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.

Начало информационного этапа

Развитие человечества все больше и больше наталкивало величайшие умы на мысли об автоматизации некоторых процессов. Начало этапа программирования приписывается по разным источникам нескольким периодам в промежутке от начала 19 до середины 20 веков. За эти десятилетия появилось множество методик написания исходного кода. Каждая из них кардинально отличается своими принципами и идеями. Рассмотрим структурное программирование, появившееся в 70-х годах прошлого столетия.

Немного истории

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

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

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

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

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

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

Языки программирования

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

Эпилог

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

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

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

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

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

    алгоритм и программа должны составляться поэтапно (по шагам).

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

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

Структурное программирование иногда называют еще "программированием без GO TO". Рекомендуется избегать употребления оператора перехода всюду, где это возможно, но чтобы это не приводило к слишком громоздким структурированным программам.

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

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

Первая (а ) структура - тип последовательность (или просто последовательность), вторая (б ) – структура выбора (ветвление), третья (в ) – структура цикла с предусловием.

При словесной записи алгоритма указанные структуры имеют соответственно следующий смысл:

«выполнить ; выполнить
»,

если , то выполнить , иначе выполнить
»,

«до тех пор, пока , выполнять »,

где - условие; , ,
- действия.

Применительно к языку Паскаль, в котором наиболее полно нашли свое отражение идеи структурного программирования, целесообразно при проектировании алгоритмов дополнительно использовать еще четыре элементарные структуры: сокращенную запись разветвления (рис. 16, ); структуру варианта (рис. 16, ); структуру повторения или цикла с параметром (рис. 16, ); структуру цикла с постусловием (рис. 6, ). Каждая из этих структур имеет один вход и один выход.

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

В зависимости от типа и числа проверяемых условий различают:

Ветвление с простым условием (условие - выражение отношения);

Ветвление с составным условием (условие - логическое выражение);

Сложное ветвление (несколько условий).

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

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

Повторяющийся участок вычисления называется циклом . Операции, осуществляемые в цикле, составляют тело цикла.

Величина, изменяющая своё значение от цикла к циклу, называется параметром цикла.

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

Полный однократный проход цикла от начала до конца называется итерацией.

Все циклические процессы по признаку определения количества повторений (М) разделяются на два класса.

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

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

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

    вход в цикл (формирование начального значения параметра цикла);

    вычисления в теле цикла (расчёт текущего значения функций, формирования нового значения параметра цикла, а также вспомогательные операции);

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

В соответствии с видом задания (изменения) параметра цикла арифметические циклы подразделяются на:

    циклы с аналитическим изменением параметра;

    циклы с табличным заданием параметра.

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

Распространены две методики (стратегии) разработки программ , относящиеся к структурному программированию:

– программирование «сверху вниз»;

– программирование «снизу вверх».

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

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

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

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

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

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

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

Достоинства структурного программирования:

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

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

– уменьшается время и стоимость программной разработки;

– улучшается читабельность программ.

Предпрограммная подготовка задачи

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

1. постановка задачи;

2. формирование математической модели задачи;

3. выбор и обоснование метода решения;

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

5. программирование;

6. отладка и тестирование программы;

7. решение задачи на ЭВМ и анализ результатов;

8. сопровождение программы.

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

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

Постановка задачи должна отвечать следующим требованиям:

Четкая формулировка цели с указанием вида и характеристик конечных результатов;

Представление значений и размерностей исходных данных;

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

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

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

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

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

Полученная математическая модель должна отвечать следующим требованиям:

Вначале составляется модель исходных данных, затем - расчетные зависимости;

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

Обозначение всех входящих в зависимости величин именами, определяющими их суть;

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

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

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

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

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

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

3. Некоторые простые приемы позволяют повысить эффективность программы (то есть уменьшить количество выполняемых операций и время работы программы). К таким приемам относится:

Использование операции умножения вместо возведения в степень;

Если некоторое арифметическое выражение встречается в вычислениях несколько раз, то его следует вычислить заранее и хранить в памяти ЭВМ, а по мере необходимости использовать;

При организации циклов в качестве границ индексов 4 использовать переменные, а не выражения, которые вычислялись бы при каждом прохождении цикла;

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

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

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

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

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

Свести количество вычислений к минимуму.

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

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

Тестирование - это испытание, проверка правильности работы программы в целом, либо её составных частей.

Отладка и тестирование (англ. test - испытание) - это два четко различимых и непохожих друг на друга этапа:

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

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

Тестирование устанавливает факт наличия ошибок, а отладка выясняет ее причину. В современных программных системах (Turbo Basic, Turbo Pascal, Turbo C и др.) отладка осуществляется часто с использованием специальных программных средств, называемых отладчиками. Эти средства позволяют исследовать внутреннее поведение программы.

Программа-отладчик обычно обеспечивает следующие возможности:

Пошаговое исполнение программы с остановкой после каждой команды (оператора);

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

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

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

В начале процесса отладки надо использовать простые тестовые данные;

Возникающие затруднения следует четко разделять и устранять строго поочередно;

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

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

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

Должна быть испытана каждая ветвь алгоритма;

Очередной тестовый прогон должен контролировать то, что еще не было проверено на предыдущих прогонах;

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

Арифметические операции в тестах должны предельно упрощаться для уменьшения объема вычислений;

Количества элементов последовательностей, точность для итерационных вычислений, количество проходов цикла в тестовых примерах должны задаваться из соображений сокращения объема вычислений;

Минимизация вычислений не должна снижать надежности контроля;

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

Усложнение тестовых данных должно происходить постепенно.

Процесс тестирования можно разделить на три этапа.

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

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

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

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

Как будет вести себя программа, работающая с массивами, если количество их элементов превысит величину, указанную в объявлении массива?

Что произойдет, если числа будут слишком малыми или слишком большими?

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

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

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

Сопровождение программы:

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

Доработка программы для решения конкретных задач;

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

1Конста́нта в программировании - способ адресования данных, изменение которых рассматриваемой программой не предполагается или запрещается.

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

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

3 Инструкция или оператор (англ. statement) - наименьшая автономная часть языка программирования; команда. Программа обычно представляет собой последовательность инструкций.

Многие языки (например, Си) различают инструкцию и определение. Различие в том, что инструкция исполняет код, а определение создаёт идентификатор (то есть можно рассматривать определение как инструкцию присваивания).

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

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

Есть три способа, как элементы массива могут быть проиндексированы целыми неотрицательными числами:

первый элемент массива имеет индекс 0;

первый элемент массива имеет индекс 1;

n («индекс началом с n»)

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

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