1 ПРИЕМЫ ОБЕСПЕЧЕНИЯ ТЕХНОЛОГИЧНОСТИ ПРОГРАММНЫХ ПРОДУКТОВ Системное и прикладное программное обеспечение Малышенко Владислав Викторович.

Презентация:



Advertisements
Похожие презентации
1 Тема 1.7. Алгоритмизация и программирование Информатика.
Advertisements

Массивы 9 класс. Основные теоретические сведения Примеры решения задач.
ОСНОВЫ ТЕХНОЛОГИИ РАЗРАБОТКИ ПРОГРАММ. Разработка программ - промышленное производство необходима технология разработки программ. Д. Кнут «Искусство программирования.
Языки и методы программирования Преподаватель – доцент каф. ИТиМПИ Кузнецова Е.М. Лекция 7.
Программирование на Pascal. Темы Повторение. Составные логические условия Повторение. Составные логические условия Повторение. Составные логические условия.
Лекция 7. Структура языка С/С++. Операторы ветвления: условный оператор if. Полное ветвление. Неполное ветвление. Оператор множественного выбора switch.
ВЫПОЛНЕНИЕ АЛГОРИТМОВ КОМПЬЮТЕРОМ. Алгоритм, записанный на «понятном» компьютеру языке программирования, называется программой. Программа данные, предназначенные.
Глава 6. УПРАВЛЯЮЩИЕ СТРУКТУРЫ Оператор присваивания Простой и составной операторы Условный оператор Оператор множественного выбора Оператор цикла с предусловием.
Структурное программирование. Стилевое оформление. Отладка программы. Комментарии Учебник Ривкинд и др. (11 класс, академ.уровень) §2.6.
Радионик Рената 9Б. Массив – это обозначаемая одним именем последовательность однотипных элементов. Место каждого элемента в этой последовательности определяется.
Автор: учитель информатики МКОУ Плесской средней общеобразовательной школы Юдин Андрей Борисович Часть 1.
1 Основы надежности ЛА Надежность сложных систем.
Одномерный массив. Цель урока: познакомить учащихся с понятием одномерный массив Задачи: дать определение массива дать представление: об описании массива.
Проектирование архитектуры ИСО 1. UML 2 Структура определения языка 4.
Таблица умножения на 8. Разработан: Бычкуновой О.В. г.Красноярск год.
Сортировка методом пузырька, выбором (Pascal) Кокарева Светлана Ивановна.
Алгоритмизация и требования к алгоритму Алгоритм и алгоритмизация Алгоритм и алгоритмизация.
Алгоритмизация и программирование. Языки программирования высокого уровня. Технологии программирования Алгоритмизация и программирование. Языки программирования.
1 Технология структурного программирования Формирует у ученика культуру программирования. Упрощает переход к более сложным и совершенным технологиям: объектно-
Транксрипт:

1 ПРИЕМЫ ОБЕСПЕЧЕНИЯ ТЕХНОЛОГИЧНОСТИ ПРОГРАММНЫХ ПРОДУКТОВ Системное и прикладное программное обеспечение Малышенко Владислав Викторович

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

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

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

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

6 Результатом объектной декомпозиции является совокупность объектов, которые затем реализуют как переменные некоторых специально разрабатываемых типов (классов), представляющих собой совокупность полей данных и методов, работающих с этими полями.

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

8 Модуль Данные модуль может получать и/или возвращать через общие области памяти или параметры. Требования к модулям: отдельная компиляция; одна точка входа; одна точка выхода; соответствие принципу вертикального управления; возможность вызова других модулей; небольшой размер (до операторов языка); независимость от истории вызовов; выполнение одной функции.

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

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

11 Сцепление по данным предполагает, что модули обмениваются данными, представленными скалярными значениями. При небольшом количестве передаваемых параметров этот тип обеспечивает наилучшие технологические характеристики программного обеспечения. Например: Function Max(a, b: integer): integer; begin if a>b then Max:=a else Max: =b; end;

12 Сцепление по образцу предполагает, что модули обмениваются данными, объединенными в структуры. Этот тип также обеспечивает неплохие характеристики, но они хуже, чем у предыдущего типа, так как конкретные передаваемые данные «спрятаны» в структуры, и потому уменьшается «прозрачность» связи между модулями. Function MaxEl(a:array of integer): integer; Var i: integer; begin MaxEl: = a[0]; for i: = 1 to High(a) do if a[i]>MaxEl then MaxEl: = a[i]; end;

13 Сцепление по управлению один модуль посылает другому некоторый информационный объект (флаг), предназначенный для управления внутренней логикой модуля. Таким способом часто выполняют настройку режимов работы программного обеспечения. Подобные настройки также снижают наглядность взаимодействия модулей. Например, Function MinMax (a, b: integer; flag: boolean): integer; begin If (a>b) and (flag) then MinMax: = a else MinMax: = b; end;

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

15 Сцепление по общей области данных Например, функция МахА, использующая глобальный массив А, сцеплена с основной программой по общей области: Function MaxA: integer; Var i:word; begin МахА: = a[Low(a)]; for i: = Low(a) + 1 to High(a) do if a[i]>MaxA then MaxA: = a[i]; end;

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

17 Характеристики различных типов сцепления Тип сцепления Сцеплен ие, балл Устойчивость к ошибкам других модулей Наглядность (понятность) Возможность изменения Вероятность повторного использовани я По данным1Хорошая Большая По образцу3СредняяХорошаяСредняя По управлению4СредняяПлохая Малая По общей области6Плохая СредняяМалая По содержимому10Плохая Малая

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

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

20 Связность модуля FF1 F2 F F F F F F F F функциональная последовательнаяинформационная процедурнаявременнаялогическая

21 Связность модуля Вид связностиСцеплен ие, балл Наглядность (понятность) Возможность изменения Сопровожда емость Функциональная10Хорошая Последовательная9Хорошая Информационная8Средняя Процедурная5Средняя Плохая Временная3Средняя Плохая Логическая1Плохая Случайная0Плохая

22 Библиотеки ресурсов Различают библиотеки ресурсов двух типов: библиотеки подпрограмм; библиотеки классов.

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

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

25 Нисходящая и восходящая разработка программного обеспечения При проектировании, реализации и тестировании компонентов структурной иерархии, полученной при декомпозиции, применяют два подхода: восходящий; нисходящий. И еще один подход - «расширение ядра».

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

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

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

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

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

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

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

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

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

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

36 схемы алгоритмов (ГОСТ )

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

38 Базовые алгоритмические структуры После того, как в 60-х годах XX в. было доказано, что любой сколь угодно сложный алгоритм можно представить с использованием трех основных управляющих конструкций, в языках программирования высокого уровня появились управляющие операторы для реализации соответствующих конструкций. Эти три конструкции принято считать базовыми. К ним относят конструкции: следование - обозначает последовательное выполнение действий; ветвление - соответствует выбору одного из двух вариантов действий; цикл-пока - определяет повторение действий, пока не будет нарушено некоторое условие, выполнение которого проверяется в начале цикла.

39 Базовые алгоритмические структуры

40 Стиль оформления программы

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

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

43 Правила именования объектов программы При выборе имен программных объектов следует придерживаться следующих правил: имя объекта должно соответствовать его содержанию, например: MaxItem - максимальный элемент; NextItem - следующий элемент; если позволяет язык программирования, можно использовать символ «_» для визуального разделения имен, состоящих из нескольких слов, например: Max_Item, Next_Itetm; необходимо избегать близких по написанию имен, например: Index и InDec.

44 Правила оформления модулей Каждый модуль должен предваряться заголовком, который, как минимум, содержит: название модуля; краткое описание его назначения; краткое описание входных и выходных параметров с указанием единиц измерения; список используемых (вызываемых) модулей; краткое описание алгоритма (метода) и/или ограничений; ФИО автора программы; идентифицирующую информацию (номер версии и/или дату последней корректировки).

45 Правила оформления модулей. Пример

46 Стиль оформления текстов модулей Стиль оформления текстов модулей определяет использование отступов, пропусков строк и комментариев, облегчающих понимание программы. Как правило, пропуски строк и комментарии используют для визуального разделения частей модуля, например: {проверка количества отрезков и выход, если отрезки не заданы} If n

47 Стиль оформления текстов модулей Для таких языков, как Pascal, C++ и Java, использование отступов позволяет прояснить структуру программы: обычно дополнительный отступ обозначает вложение операторов языка, например: аmах: = а[1,1]; for i: = 1 to n do for j: = 1 to t do if a[i,j]>amax then amax: = a[i,j];

48 Стиль оформления текстов модулей Опыт показывает, что переводить с английского языка каждый оператор программы не нужно. Комментировать следует цели выполнения тех или иных действий, а также группы операторов, связанные общим действием, т. е. комментарии должны содержать некоторую дополнительную (неочевидную) информацию, например: {проверка условия и выход, если условие не выполняется} If n

49 Стиль оформления текстов модулей Для языков низкого уровня, например, Ассемблера, стиль, облегчающий понимание, предложить труднее. В этом случае может оказаться целесообразным комментировать и блоки операторов, и каждый оператор, например: ; цикл суммирования элементов массива ; установки цикла mov AX, 0 ;обнуляем сумму mov CX, n ;загружаем счетчик цикла mov BX, 0 ;смещение первого элемента массива ; тело цикла cycle: add AX, a [BX] ;добавляем элемент add BX, 2 ;определяем адрес следующего loop cycle ;цикл на n повторений ; выход из цикла при обнулении счетчика

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

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

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

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

54 Способы экономии памяти. Передача данных в подпрограмму Также следует помнить, что при передаче структурных данных в подпрограмму «по значению» копии этих данных размещаются в стеке. Избежать копирования иногда удается, если передавать данные «по ссылке», но как неизменяемые (описанные const). В последнем случае в стеке размещается только адрес данных, например: Type Massiv = array [ ] of real; function Summa (Const a:Massiv;...)...

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

56 Способы уменьшения времени выполнения. Пример Пусть имеется цикл следующей структуры (Pascal): for y: = 0 to 99 do for x: = 0 to 99 do a [320*x+y]: = S [k,l]; В этом цикле операции умножения и обращения к элементу S[k] выполняются раз. Оптимизируем цикл, используя, что 320 = : skl: =S [k,l]; {выносим обращение к элементу массива из цикла} for x: = 0 to 99 do (меняем циклы местами} begin i:= x shl 8 + x shl 6; {умножение заменяем на сдвиги и выносим из цикла} for y; = 0 to 99 do a [i+y]: =skl; end;...

57 Способы уменьшения времени выполнения. Пример 2 Пусть имеется цикл, в теле которого реализовано сложное условие: for k: = 2 to n do begin if x[k] > yk then S: = S+y[k]-x[k]; if (x[k]< = yk) and (y[k]yk then S:=S+y[k]-x[k] else if y[k]

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

59 Способы проявления ошибок

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

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

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

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

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

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

66 Обработка исключений Поскольку полный контроль данных на входе и в процессе вычислений, как правило, невозможен, следует предусматривать перехват обработки аварийных ситуаций. Для перехвата и обработки аппаратно и программно фиксируемых ошибок в некоторых языках программирования, например, Delphi Pascal, C++ Java, предусмотрены средства обработки исключений. Использование эти средств позволяет не допустить выдачи пользователю сообщения об аварийном завершении программы, ничего ему не говорящего. Вместо этого программист получает возможность предусмотреть действия, которые позволяют исправить эту ошибку или, если это невозможно, выдать пользователю сообщение с точным описанием ситуации и продолжить работу.

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

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

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

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

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

72 Кратко Понятие технологичности программного обеспечения; Модули и их свойства; Нисходящая и восходящая разработка программного обеспечения; Структурное и «неструктурное» программирование; Стиль оформления программы; Эффективность и технологичность; Программирование «с защитой от ошибок»; Сквозной структурный контроль.