Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТРПП пособие Шишов.doc
Скачиваний:
131
Добавлен:
17.11.2018
Размер:
3.25 Mб
Скачать

13.4. Программирование «с защитой от ошибок»

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

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

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

При его использовании существенно уменьшается вероятность получения неверных результатов.

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

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

  • При использовании массива его размер следует задавать константой и указывать ее отдельно, используя далее эту константу во всей программе.

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

  • В программе следует предусмотреть защиту от неправильного ввода (она не должна выполняться, если данные выходят за пределы допустимого диапазона).

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

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

  • Выбирайте такой способ представления данных, который упрощает программу.

  • Убедитесь, что входные данные соответствуют принятым ограничениям.

  • Обеспечьте распознавание неверно заданных входных данных.

  • Стремитесь в первую очередь к получению правильной программы и только потом к сокращению времени ее выполнения.

  • Стремитесь к простой, а не к сложной программе.

  • Четко и ясно выражайте свои мысли в комментариях.

  • Не бойтесь переписывать неудачные участки ПО.

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

  • арифметическое выражение, которое несколько раз вычисляется в программе, лучше вычислить один раз и присвоить его значение переменной, которую и можно везде использовать вместо арифметического выражения;

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

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

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

• правильность выполнения операций ввода–вывода;

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

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

  • ошибки передачи – аппаратные средства, например, вследствие неисправности, искажают данные;

  • ошибки преобразования – программа неверно преобразует исходные данные из входного формата во внутренний;

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

  • ошибки данных – пользователь вводит неверные данные. Ошибки передачи обычно контролируются аппаратно.

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

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

Неверные данные обычно может обнаружить только пользователь.

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

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

Например:

• если каким–либо образом вычисляется индекс элемента массива, то следует проверить, что этот индекс является допустимым;

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

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

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

• избегать вычитания близких чисел (машинный ноль);

• избегать деления больших чисел на малые;

• сложение длинной последовательности чисел начинать с меньших по абсолютной величине;

• стремиться по возможности уменьшать количество операций;

• использовать методы с известными оценками погрешностей;

• не использовать условие равенства вещественных чисел;

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

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