- •Содержание
- •Предисловие
- •1. Этапы разработки программы
- •1.1. Формальная постановка задачи
- •1.2. Выбор метода решения
- •1.3. Внешняя спецификация программы
- •1.4. Разработка алгоритма
- •1.5. Кодирование алгоритма на языке программирования
- •1.6. Испытания программы на тестах
- •Вопросы для самоконтроля
- •2. Язык для записи алгоритмов
- •2.1. Базовые типы величин
- •2.2. Объявление величин в алгоритме
- •2.3. Структура компьютера с позиций программы
- •2.4. Базовые операции
- •2.5. Управляющие структуры
- •2.6. Структура алгоритма
- •Вопросы для самоконтроля
- •3. Введение в язык программирования паскаль
- •3.1. Краткая характеристика языка
- •Алфавит, лексемы, разделители
- •3.1.2. Структура программы
- •3.2. Средства кодирования вычислительных операций
- •3.2.1. Операция ввода
- •3.2.2. Операция присваивания
- •3.2.3. Операция вывода
- •3.3. Средства кодирования управляющих конструкций
- •3.3.1. Кодирование структуры «Ветвление»
- •3.3.2. Кодирование структуры «Цикл»
- •3.4. Кодирование алгоритма в целом
- •Заключение
- •Вопросы для самоконтроля
- •Разработка алгоритмов методом пошаговой детализации
- •4.1. Структура алгоритма
- •4.2. Описание действий
- •4.3. Обратная подстановка
- •4.4. Пример
- •4.4.1. Разработка внешней спецификации
- •4.4.2. Разработка главного алгоритма
- •4.4.3. Подстановка
- •4.4.4. Кодирование на языке Паскаль
- •4.4.5. Разработка алгоритма подпрограммы сортировки
- •4.5. Вопросы для самоконтроля
- •5.Тестирование
- •5.1. Общие принципы тестирования
- •5.2. Виды тестирования
- •5.3. Стратегии тестирования
- •5.3.1. Методы стратегии «черного ящика»
- •5.3.2. Методы стратегии «белого ящика»
- •5.4. Правила записи трассировки
- •Вопросы для самоконтроля
- •6. Характеристики качества программы
- •Вопросы для самоконтроля
- •Вопросы для самоконтроля (продолжение)
- •7. Типовые алгоритмы обработки массивов
- •А1. Ввод массива с клавиатуры
- •А7. Выбор элементов по условию
- •А8. Проверка выполнения некоторого условия
- •Пример 2. ”Найти значение элемента, встречающегося в массиве наибольшее количество раз”.
- •Пример 3. В матрице a[1..N, 1..M] поменять местами первый и третий отрицательные элементы, встретившиеся при просмотре матрицы по строкам слева направо и сверху вниз.
- •8. Обработка символьной информации
- •8.1. Обработка строк
- •8.2. Особенности ввода информации строкового вида
- •Вопросы для самоконтроля
- •9. Типы данных, задаваемых пользователем
- •9.1. Множества
- •9.2. Записи
- •9.3. Оператор with
- •Вопросы для самоконтроля
- •10. Файлы
- •Введение
- •10.2. Классификация файлов в Турбо-Паскале
- •10.3. Объявление файла
- •10.4. Открытие и закрытие файла
- •10.5. Чтение и запись
- •10.6. Текстовые файлы
- •10.7. Нетипизированные файлы
- •10.8. Пример. Программа работы с файлами
- •Вопросы для самоконтроля
- •11. Подпрограммы
- •11.1. Область действия идентификаторов
- •11.2. Способы передачи параметров
- •11.3. Примеры
- •Вопросы для самоконтроля
- •12. Динамические структуры данных
- •12.1. Указатели
- •12.2. Динамические структуры типа «Список»
- •12.3. Средства языка Паскаль для организации списков
- •12.4. Типовые алгоритмы работы со списками
- •А1. Инициализация списка. (Создание нового и пустого списка)
- •А2. Добавить элемент в конец односвязного списка
- •А9. Добавить элемент в упорядоченный односвязный список
- •Задачи для закрепления материала
- •Вопросы для самоконтроля
- •13. Динамические структуры данных типа «дерево»
- •13.1. Определение дерева и способы представления в программе
- •13.2. Рекурсия
- •1. Наличие тривиального случая.
- •2. Определение сложного случая в терминах более простого.
- •13.3. Алгоритмы работы с деревьями
- •А1. Вычисление суммы значений информационных полей элементов
- •А2. Подсчет количества узлов в бинарном дереве
- •А3. Подсчет количества листьев бинарного дерева
- •A5. Поиск элемента в двоичном упорядоченном дереве
- •Вопросы для самоконтроля
- •14. Модули
- •14.1. Введение
- •14.2. Форма модульной программы
- •14.3. Стандарты структурного программирования
- •14.4. Модули в турбо-паскале
- •14.5. Использование модулей
- •14.6. Стандартные модули Турбо-Паскаля
- •14.7. Пример использования модулей
- •Вопросы для самоконтроля
- •15. Основы объектно-ориентированного программирования
- •15.1. Основные понятия
- •15.2. Объявление классов объектов
- •15.3. Статические и динамические объекты
- •15.4. Правила построения и использования объектов а. Правила наследования
- •Б. Виртуальные методы
- •В. Ранее и позднее связывание
- •Г. Совместимость классов объектов
- •Вопросы для самоконтроля
- •Заключение
- •Библиографический список
5.4. Правила записи трассировки
Под трассировкой понимается выполнение алгоритма последовательно, операция за операцией, с фиксацией результатов каждой операции. Трассировка может выполняться вручную и на компьютере, используя при этом имеющиеся программные средства отладки. При выполнении тестов «вручную» с фиксацией результатов на бумаге рекомендуется придерживаться следующих правил:
В качестве результатов операций ввода и присваивания записываются новые значения переменных (в виде тождеств).
В качестве результата операции вывода изображается текст, сформированный для выводимых значений.
Условие (в операциях ветвления и цикла) записывается в виде отношений, в которых все переменные заменены их текущими значениями. Условие помещается в фигурные скобки и затем записывается результат в форме «да/нет».
Трассировку следует начинать с первой операции исполнимой части алгоритма, а их результаты записываются последовательно, в порядке их выполнения.
Для всех, не детализированных в данном алгоритме, действий и подпрограмм результаты считать сформированными правильно.
Трассировка должна быть прекращена только по достижении строки «конец» алгоритма.
Только после этого надо приступить к анализу результатов алгоритма. Именно за счет этого появляется возможность увидеть такие результаты, которых программа не должна делать, но из-за ошибки в алгоритме делает.
В качестве примера приведем запись трассировки изображенного выше фрагмента из двух последовательных конструкций «если» для теста номер 1, построенного по методу комбинированного покрытия условий.
Дано: {a=2, b=0, x=4}
Требуется: {x=3}
Трассировка:
{ {2>1}да и {0=0}да }да
x = 2
{ {2=2}да и {2>1}да }да
x = 3
Конец.
Вывод: Полученный результат (x=3) совпадает с эталонным. Ошибки нет.
Вопросы для самоконтроля
Что такое «тест»? Каково его назначение?
Какой тест является хорошим и какой плохим?
Сколько тестов требуется для получения уверенности, что программа работает правильно?
Дайте качественное определение термина «система тестов».
Перечислите виды тестирования?
Какой вид тестирования более удобен на этапе разработки программы?
Что понимается под стратегией тестирования?
В чем отличия стратегий «черного ящика» и «белого ящика»?
Что понимается под классом эквивалентности?
Какие критерии используются при выделении классов эквивалентности?
В чем суть метода граничных условий?
Перечислите и вкратце охарактеризуйте методы стратегии «белого ящика».
В чем отличия методов покрытия решений и покрытия условий?
Что понимается под термином «трассировка»?
Перечислите правила записи трассировки?
6. Характеристики качества программы
Разработка программы представляет собой комбинаторный процесс. В результате его может быть получен не один, а несколько вариантов программ, решающих одну и ту же задачу. И разные варианты будут отличаться по своим характеристикам. Рассмотрим характеристики качества программы на примере программы решения следующей задачи.
Задача: Определить, является ли заданное число простым. Напомним, что простым считается такое целое число, которое делится только само на себя и на единицу. Ниже приведен текст программы, призванной решить задачу.
Основная идея алгоритма заключается в следующем: если число N не будет делиться без остатка ни на одно из чисел натурального ряда, меньшее чем N, то оно, согласно определению, будет простым.
Приведенная программа написана на языке Паскаль и имеет имя Simple.
В разделе описаний объявлены следующие переменные:
N – типа целых – исходное (проверяемое) число
I – типа целых – возможный делитель (параметр цикла)
F – логический (булевский) тип – признак «делитель найден».
Последовательность действий в программе следующая:
Вводим число N. Присваиваем признаку F значение “ложь”. В цикле просматриваем все возможные делители. Если остаток от деления равен нулю, устанавливаем признаку F значение «истина».
Наконец, анализируем значение признака F и выводим результат в виде строки текста.
Рассмотрим, отвечает ли наша программа критериям качества.
Корректность (правильность) - это строгое и полное соответствие конечных результатов выполнения программы требованиям постановки задачи.
Нашу программу можно считать правильной, поскольку результат ее выполнения соответствует условиям задачи определения принадлежности числа множеству простых чисел. Однако она не удовлетворяет многим другим критериям качества.
Надежность - это способность программы обеспечивать устойчивость функционирования при возникновении отклонений, вызванных ошибками входных данных, сбоями технических средств и обслуживания, а также способность программы сохранять работоспособность в заданных режимах и при заданных объемах обрабатываемой информации.
Наша программа не контролирует правильность ввода исходного числа: если пользователь введет отрицательное число, результат будет ошибочным.
Чтобы избавиться от этой ошибки, введем контроль введенного значения и завершение работы программы в случае ошибки. Текст программы с указанными изменениями теперь выглядит так:
Теперь программа будет функционировать надежнее.
Удобство применения – это способность программы обеспечивать простоту ввода исходных данных и получение результатов в наиболее понятной и наглядной форме.
Для этого программа должна:
формировать запрос на ввод данных в понятной форме
снабжать комментариями вывод результатов
информировать пользователя об ошибках при задании входных данных и (при диалоговом режиме работы программы) дать ему возможность исправить ошибку.
Наша программа (ее вторая версия):
не выводит запрос на ввод данных
не информирует об ошибке (при вводе отрицательного числа)
не позволяет исправить эту ошибку.
Исправим программу следующим образом:
Вместо оператора «goto LabErr» используем конструкцию «repeat … until», обеспечив повторение запроса на ввод данных до тех пор, пока они не будут введены правильно. Кроме этого дополнительно поместим операторы вывода сообщения о назначении программы.
Теперь текст программы примет следующий вид:
Эффективность по быстродействию и по затратам памяти характеризуется зависимостью времени работы программы или затрат основной памяти от размера исходных данных. В этом контексте говорят о временнóй (ударение на «о») и емкостной сложности программы.
Поведение временнóй сложности в пределе при увеличении размера задачи называется асимптотической временнóй сложностью программы.
Зависимости могут быть различными, например:
линейными, когда временнáя сложность линейно зависит от N (например, при вычислении суммы элементов массива)
квадратичными, когда временнáя сложность имеет порядок N2 (например, при сортировке массива)
логарифмическими, когда время решения пропорционально log2N (например, при поиске в упорядоченном массива методом деления интервала пополам).
Асимптотическая временнáя сложность – важная характеристика алгоритма и программы, построенной на ее основе. Выбор более оптимального алгоритма, если это в принципе возможно, с меньшей асимптотической временнóй сложностью позволит значительно сократить время работы программы.
В нашей программе асимптотическая временнáя сложность – линейная (за счет использования цикла со счетчиком «for I:=2 to N-1 do». Однако можно заметить, что для поиска делителя достаточно просмотреть числа от 2 до корня квадратного от N, и в этом случае асимптотическая временнáя сложность программы уменьшится и станет пропорциональной корню квадратному от N. При этом вместо приведенного выше оператора цикла потребуется два:
imax:=round(sqrt(N));
for I:=2 to imax do
Кроме того, время работы программы можно сократить еще, если прекращать выполнение цикла, как только будет найден первый делитель. Для этого заменим оператор цикла со счетчиком (for) на оператор цикла с предусловием (while).
Текст новой (четвертой) версии программы примет следующий вид:
Эта программа будет работать значительно быстрее. А говорить о ее емкостной сложности нет смысла.
Удобство сопровождения - это способность программы обеспечивать простоту процесса поддержания программы (программного обеспечения) в работоспособном состоянии и простоту внесения в нее необходимых модификаций.
Это свойство обеспечивается правильным оформлением текста программы и наличием необходимой программной документации.
Для простоты сопровождения требуется:
Структурированность программы
Наличие комментариев в тексте программы
Имена переменных должны нести смысловую нагрузку или соответствовать общепринятым обозначениям. (В нашем примере вместо безличного имени F для признака «делитель найден» лучше использовать более информативное имя, например, FlagFound).
Структурированность программы достигается за счет выполнения следующих требований к ее записи:
Программа составляется на базе ограниченного набора простых конструкций (следование, ветвление, цикл) без использования переходов с помощью оператора goto.
Конструкции записываются с отступами так, чтобы была видна структура программы.
В нашем случае программа структурирована только частично. В ней нарушены правила ступенчатой записи конструкции «если» в теле цикла repeat . . until и в конце программы.
Наличие комментариев обеспечивает так называемую самодокументированность программы. Для достижения этого рекомендуется снабдить комментариями все основные переменные и части программы.
Текст программы (версия 5), после внесения в него изменений, примет вид, удовлетворяющей рассмотренным выше критериям. Он приведен на следующей странице.
Мобильность универсальность) – это возможность перенесения программного обеспечения с одного типа ЭВМ на другой или с одной платформы (операционной среды) на другую.
Наша программа построена с использованием версии языка Паскаль, соответствующей стандарту ISO (Международной организации стандартов), и поэтому она может быть легко перенесена в другие операционные среды и на другие типы ЭВМ
