ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 20.05.2023

Просмотров: 443

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Опасность 1: Переполнение (получение очень больших чисел).

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

Опасность 2: Переполнение или потеря значимости в промежуточных вычислениях.

Конечный результат может иметь нормальный вид, но промежуточные могут оказаться слишком большими или слишком маленькими. Естественно, о правильности конечного результата в данном случае говорить не приходится. Для машинной арифметики порядок выполнения операций может оказаться весьма существенным. Это в математике a*b/c=a/c*b. В программировании - не всегда.

2.3 Передача управления

1. Развилки

Опасность: Пропущена ветвь «иначе».

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

  1. Вложенные условные операторы

Одинаковая запись в разных языках программирования трактуется по-разному.

  1. Циклы

Опасность: Зацикливание.

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

2.4 Подпрограммы

1. Вызов подпрограммы

Опасность 1: Неверное количество параметров.

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

Опасность 2: Неверные типы параметров.

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

Опасность 3: Неверный порядок следования параметров.

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


2. Использование параметров внутри подпрограммы

Опасность: Неверные единицы измерения параметров.

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

Использование формального параметра внутри подпрограммы для изменения значения соответствующего фактического параметра

Опасность: Неверный способ передачи параметров.

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

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

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

К счастью, в большинстве языков такое запрещено.

  1. Использование внутри подпрограммы формальных параметров, передаваемых по ссылке

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


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

  1. Использование внутри подпрограммы глобальной переменной и параметра, передаваемого по ссылке

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

2.5 Файлы

1. Запись/чтение двоичных файлов

Опасность: Путаница между файлами разных типов.

  1. Создание файлов с данными с помощью текстового редактора. Просмотр файлов с данными с помощью текстового редактора

Опасность: Путаница текстовых и двоичных файлов.

  1. Запись/чтение не типизированных файлов

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

  1. Запись в файл

Опасность: Отсутствие явного закрытия файлов.

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

Глава 3. ОТЛАДКА

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

3.1 Место проявления ошибки и место нахождения ошибки

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

a= 0;

if (x>3) {a= 10;}

b= 1/a;

Место проявления ошибки в данном случае — третий оператор фрагмента:

b=1/a. Но место нахождения ошибки указать так определенно нельзя. Возможно, что ошибка в третьем операторе, и в знаменателе должна стоять не переменная a, а какое-то другое выражение. Возможно, что ошибка в первом операторе, и переменной a должно было быть присвоено другое ненулевое значение. Возможно, что ошибка во втором операторе, и там потеряна ветвь «иначе», при выполнении которой переменная a должна была поменять свое значение на значение не равное нулю.


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

3.2 Методы поиска ошибки

3.2.1 Индуктивный и дедуктивный

Для поиска ошибок существует два подхода: индуктивный и дедуктивный.

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

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

основания подозревать ошибку.

Дедуктивный подход означает движение от общего к частному. Что в принципе могло произойти? Исходя из соображений, формируется множество гипотез. Затем оно уточняется: какие-то гипотезы исключаются как несоответствующие имеющимся признакам ошибки, какие-то уточняются за счет дополнительной информации. Например: программа нормально заканчивает вычисления, но выдает странные результаты. На выходе ожидались два числа, близких к единице с одним знаком после запятой. Получили одно число очень большое, а второе — со странной непериодической дробной частью. Известно, что «странные» выходные данные могут получиться в нескольких случаях. Либо если в вычислениях участвовала неинициализированная переменная, либо при вводе из файла «не тех» значений (например, файл готовился как текстовый, а читался как типизированный), либо при неверной передаче значения параметра из подпрограммы, либо при неправильных вычислениях (например, требующих слишком больших или слишком маленьких промежуточных результатов). Из этого следует что, надо проверить, все ли переменные, использованные при вычислении «странного» результата, были явно инициализированы. Не использовались ли значения, которые введенные из файла? Если да, то что за данные лежат в этом файле. Не было ли передачи параметра из подпрограммы? Если да, то передается ли этот параметр по ссылке? Результатом, каких именно вычислений являются «странные» значения? Не возникли ли по ходу этих вычислений слишком больших или слишком маленьких промежуточных результатов?


3.2.2 Ретроанализ

Раньше в шахматных журналах были очень популярны задачи на ретроанализ. Выглядели они так. Дается ситуация, при которой белые ставят мат в один ход и черные ставят мат в один ход. Вопрос: кто выиграет? То есть надо разобраться, чей сейчас ход. А для этого «открутить» игру назад и понять, каким образом сложилась описанная в задаче ситуация. Как ретроанализ выглядит применительно к отладке? Находим место ошибки. Ошибка связана с тем, что некоторые переменные имеют определенные значения. Проследим назад по программе, откуда эти значения взялись. Они были вычислены через некоторые другие переменные. А откуда взялись значения этих других переменных? И так далее.

Пример:

int a = in.nextInt();

b= 7;

c= a + b;

d= 1/c;

При вычислении d возникает деление на нуль. Значит, переменная c в этом операторе равна нулю. Возможны два варианта. Либо ошибочно выражение, записанное в знаменателе (знаменатель должен быть отличен от c), либо переменная c имеет неверное значение. Если выражение в знаменателе правильно, значит, переменная c имеет неверное значение. Откуда взялось значение переменной c? Поднимаемся вверх по программе. Переменная c получила значение из выражения a+b. Значит, либо в этой позиции должно стоять другое выражение, либо что-то не так со значениями переменных a и b. Откуда взялись значения этих переменных? Опять поднимаемся вверх по программе. И так далее. Не всегда картина бывает такой ясной. Разбираться приходится и с развилками, и с циклами, и с подпрограммами. Но принципиальная схема именно такова.

3.3 Принципы отладки

1. Не экспериментировать. Исправление ошибок наугад не допустимо.

2. Исправлять поочередно. Одновременное внесение в программу нескольких исправлений существенно затрудняет анализ последствий каждого из них.

3. Необходимо найти ошибку, которая бы объясняла все 100% симптомов.

4. Там, где есть ошибка, может быть еще.

5. Исправление может внести новую ошибку.

3.4 Анализ ошибок

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

1. Когда была сделана ошибка?

На каком этапе работы над программой допущена ошибка: при постановке задачи, при проектировании программы, при написании текста на языке программирования и т. д.