- •Средства разработки программ на Паскале
- •Структура Паскаль-программы
- •Комментарии
- •Директивы компилятора
- •Идентификаторы
- •Переменные и типы данных
- •Константы
- •Неименованные константы
- •Нетипизированные константы
- •Типизированные константы
- •Простейшие операторы
- •Метки и безусловный переход
- •Ввод и вывод: консоль
- •Ввод с консоли
- •Вывод на консоль
- •Форматный вывод
- •Пример простейшей программы на языке Pascal
- •Типы данных
- •Порядковые типы данных
- •Стандартные подпрограммы, обрабатывающие порядковые типы данных
- •Типы данных, относящиеся к порядковым
- •Вещественные типы данных
- •Конструируемые типы данных
- •Операции и выражения
- •Совместимость типов данных
- •Приведение типов данных
- •Ветвления, массивы, циклы
- •Массивы
- •Операторы циклов
- •Сортировки массивов
- •Быстрая сортировка
- •Символы и строки
- •Неименованные константы
- •Нетипизированные константы
- •Типизированные константы
- •Операции
- •Стандартные функции
- •Стандартные функции и процедуры обработки строк
- •Операции со строками Сравнения
- •Обращение к компонентам строки
- •Конкатенация
- •Множества
- •Описание множеств
- •Множество-константа Неименованная константа
- •Нетипизированная константа
- •Типизированная константа
- •Операции с множествами
- •Представление множеств массивами
- •Представление множеств линейными массивами
- •Представление множеств битовыми массивами
- •Примеры использования символов, строк и множеств
- •Что такое файл
- •Когда нужно использовать файлы
- •Разновидности файлов
- •Описание файлов
- •Текстовые файлы Назначение файла
- •Открытие файла
- •Закрытие файла
- •Считывание из файла
- •Запись в файл
- •Пробельные символы
- •Пример использования файлов
- •Решение
- •Реализация
- •Изменение реакции на ошибку
- •Описание записей
- •Задание записей константой
- •Доступ к полям
- •Оперирование несколькими полями
- •Вложенные операторы with
- •Запись с вариантной частью
- •Описание записи с вариантной частью
- •Механизм использования записи с вариантной частью
- •Бинарные файлы
- •Типизированные файлы
- •Описание типизированных файлов
- •Назначение типизированного файла
- •Открытие и закрытие типизированного файла
- •Считывание из типизированного файла
- •Поиск в типизированном файле
- •Запись в типизированный файл
- •Поиск в нетипизированном файле
- •Запись и чтение
- •Подпрограммы обработки директорий
- •Применимость подпрограмм обработки файлов
- •Процедуры и функции Подпрограммы
- •Список параметров
- •Возвращаемые значения
- •Вызов подпрограмм
- •Способы подстановки аргументов
- •Параметр-значение Описание
- •Механизм передачи значения
- •Параметр-переменная Описание
- •Механизм передачи значения
- •Параметр-константа Описание
- •Механизм передачи значения
- •Области действия имен Разграничение контекстов
- •Побочный эффект
- •Совпадение имен
- •Нетипизированные параметры
- •Явное преобразование типа
- •Совмещение в памяти
- •Открытые параметры
- •Открытые массивы
- •Рекурсивные подпрограммы Динамические структуры данных
- •Операции
- •Очередь
- •Операции
- •Рекурсия
- •Рекурсивные подпрограммы
- •Пример рекурсивного алгоритма
- •Алгоритм решения
- •Стековая организация рекурсии
- •Ограничение глубины рекурсии
- •Замена рекурсивных алгоритмов итеративными
- •Пример сравнения рекурсивного и нерекурсивного алгоритма
- •Рекурсивный алгоритм
- •Реализация рекурсивного алгоритма
- •Полный перебор с отсечением
- •Нерекурсивный алгоритм
- •Реализация нерекурсивного алгоритма
- •Иллюстрация
- •Эффективность
- •Быстрая сортировка2
- •Алгоритм Быстр
- •Реализация алгоритма Быстр
- •Эффективность алгоритма Быстр
- •Адреса и указатели. Списочные структуры данных Статически выделяемая память
- •Разыменование
- •Присваивания
- •Сравнения
- •Динамически распределяемая память
- •Динамическое выделение памяти Типизированные указатели
- •Нетипизированные указатели
- •Динамическое освобождение памяти Типизированные указатели
- •Нетипизированные указатели
- •Списочные структуры
- •Структура списков
- •Описание списков
- •Оперирование элементами списка Хранение списка
- •Обращение к элементам списка
- •Создание списков
- •Просмотр элементов списка
- •Удаление элементов списка
- •Перестройка списков
- •Примеры перестройки линейных списков
- •Реализация
- •Создание дружественного интерфейса
- •Заставка
- •Ввод информации
- •Приглашения
- •Вывод информации
- •Технология программирования и отладка Советы по технологии написания быстро отлаживаемых программ
- •Имена, имена, имена...
- •Кусочки, куски и кусищи...
- •Спасение утопающих - дело рук самих утопающих
- •Отладка и тестирование
- •Поиск и исправление ошибок
- •Правила составления тестов
- •Оптимизация программ
- •Учебники к курсу
Правила составления тестов
Для того чтобы отладить программу, нужно проверить ее работоспособность на каких-то входных данных. Следовательно, эти входные данные нужно каким-то образом подобрать. Затем, после выполнения программы на этих входных данных, нужно сравнить полученный результат с тем, который должен получиться, если программа работает правильно. Этот процесс и называется тестированием.
Заметим, что если полученный результат отличается от эталонного, то тест считается удачным (!), потому что он помог обнаружить ошибку. А если полученный ответ совпал с правильным - радоваться рано. Один тест не может полностью проверить всю программу, ошибка вполне могла затаиться в той части, которая осталась на сей раз невыполненной. Для того чтобы протестировать всю программу, проверить все возможные частные случаи, составляют не один тест, а набор тестов.
И здесь существуют следующие правила.
Правило 1. Любой тест должен состоять не только из входных, но и из соответствующих им выходных данных. Ведь для того чтобы понять, верный или неверный результат выдала вам программа, необходимо самому знать правильный ответ.
Проверяйте вручную результаты тестов, с помощью которых вы отлаживаете программу. Немногого можно добиться, если выдаваемый программой правильный ответ вы считаете неверным и продолжаете поиск несуществующей ошибки. Хуже того - если вы все-таки добьетесь, чтобы программа выдавала ожидаемый вами неверный результат, объяснить ее неправильное поведение на других тестах вам будет еще сложнее.
Из двух предыдущих абзацев вытекает очень важный вывод: нельзя строить тесты при помощи генератора случайных чисел. Конечно, вы можете случайным образом составить входные данные, но как быть с правильным ответом? Откуда его взять, если вы сами понятия не имеете, что там подается на вход?
Правило 2. После того как программа начала правильно работать на одном или нескольких простых тестах, усложните задания, введите тест на граничные условия или тест, содержащий значения, выходящие за рамки формата входных данных. Иногда ошибка может скрываться в тех частях программы, которые кажутся самыми прозрачными. Например, в проверке нескольких переменных на равенство между собой. Если до сих пор все переменные в тестах были разными, попробуйте прогнать программу через тесты, в которых сравниваемые значения будут совпадать - все сразу или только некоторые из них в разных комбинациях.
Правило 3. Не ограничивайтесь только похожими тестами.
Все тесты можно разделить на три группы: регулярные, граничные и критические. Например, при заданных ограничениях на параметр 0 <= x <= 100 регулярными будут все тесты, где 1 <= x <= 99; граничными, где х = 0 и х = 100; остальные - критическими. Если ваша программа правильно работает для пяти-шести тестов из какой-либо группы, можно предположить, что она выдаст правильный результат и для всех остальных тестов из этой группы.
В тестовом наборе, составленном для проверки программ, обязательно должны присутствовать тесты первых двух групп, а для проверки работоспособности "защиты от дурака" (см. лекцию 14) - и третьей тоже. Если входных параметров несколько - комбинируйте! Пусть в одном и том же тесте первый параметр будет граничным, второй - регулярным, а третий - критическим. Всегда интересно посмотреть, достаточно ли надежна ваша программа, справится ли она с таким заданием.
В хорошей, надежной программе всегда нужно писать проверку того, что файл ввода существует, не пуст и содержит данные в правильном формате, что считываемые из входного файла данные попадают в определенные условием задачи диапазоны.
Правило 4. Исправления, вносимые в программу, могут повлиять на результаты нескольких тестов.
После того, как вы нашли и исправили ошибку, вновь выполните программу на всех тех тестах, которые раньше не были успешными (то есть выдавали правильные ответы) - а вдруг найдется новая ошибка?
Вообще же, составление исчерпывающих тестовых наборов для тестирования любой программы - задача очень нетривиальная, зачастую требующая математического доказательства полноты.