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

6.3.3.4 Ошибки при сравнениях

1. Сравниваются ли в программе величины, имеющие несовместимые типы данных (например, строка символов с адресом)?

2. Сравниваются ли величины различных типов или величины различной длины? Если да, то проверьте, правильно ли интерпретируются (поняты) правила преобразования.

3. Корректны ли операторы сравнения? Программисты часто путают такие отношения, как наибольший, наименьший, больше чем, не меньше чем, меньше или равно.

4. Каждое ли булевское выражение сформулировано так, как это предполагалось? Программисты часто делают ошибки при написании логических выражений, содержащих операции «И», «ИЛИ», «НЕ».

5. Являются ли операнды булевских выражений булевскими? Существуют ли ошибочные объединения сравнений и булевских выражений? Они представляют другой часто встречающийся класс ошибок. Примеры нескольких типичных ошибок приведены ниже. Если величина L определена как лежащая в интервале между 2 и 10, то выражение 2<L<10 является неверным. Вместо него должно быть написано выражение (2 < L)&(L < 10). Если же величина L определена как большая, чем Х или Y, то выражение L>X|Y является неверным; оно должно быть записано в виде (L>Х) | (L>Y). При сравнении трех чисел на равенство выражение IF (A=B=C) означает совсем другое. Например, в языке Си произойдет присвоение переменным A и B значения переменной C. А условие будет истинным, если это значение ненулевое. В случае необходимости проверить математическое отношение X=Y=Z правильным будет выражение (X=Y)&(Y=Z). Также в языке Си следует различать булевские и битовые операторы. Например, если A = 1 и B = 2, то условие IF(A && B) будет истинно, а IF(A & B) — ложно.

6. Сравниваются ли в программе мантиссы или числа с плавающей запятой, которые представлены в машине в двоичной форме? Это является иногда источником ошибок из-за усечения младших разрядов. Или из-за неточного равенства чисел в двоичной и десятичной формах представления.

7. Верны ли предположения о порядке оценки и следовании операторов для выражений, содержащих более одного булевского оператора? Иными словами, если задано выражение (А==2)&(В==2)|(С==3), понятно ли, какая из операций выполняется первой: И или ИЛИ?

8. Влияет ли на результат выполнения программы способ, которым конкретный компилятор выполняет булевские выражения? Например, оператор

IF (ХО)&((Y/X)>Z)

является приемлемым для некоторых компиляторов PL/1 (т.е. компиляторов, которые заканчивают проверку, как только одно из выражений оператора «И» окажется ложным), но приведет к делению на 0 при использовании других компиляторов.

6.3.3.5 Ошибки в передачах управления

1. Если в программе содержится переключатель (например, вычисляемый оператор GO TO в Фортране или его аналог ON… GOTO в Бейсике), то может ли значение индекса когда-ли­бо превысить число возможных переходов? Например, всегда ли L будет принимать значение 1, 2 или 3 в операторе Фортрана GO TO (200, 300, 400), L или операторе Бейсика ON L GOTO 200, 300, 400?

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

3. Будут ли программа, модуль или подпрограмма, в конечном счете, завершены?

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

DO WHILE (NOTFOUND)

DO I=X ТО Z

если первоначальное значение NOTFOUND — ложь или если Х больше Z?

5. Для циклов, управляемых как числом итераций, так и булевским условием (например, цикл для организации поиска), какова последовательность «погружения в тело цикла»? Например, что произойдет с циклом, имеющим заголовок

DO I=1 ТО TABLESIZE WHILE (NOTFOUND)

если NOTFOUND никогда не принимает значение «ложь»?

6. Существуют ли какие-ни­будь ошибки «отклонения от нормы» (например, слишком большое или слишком малое число итераций)?

7. Если язык программирования содержит понятие группы операторов (например, DO-груп­пы в PL/1, ограниченные операторами DO-END), то имеется ли явный оператор END для каждой группы и соответствуют ли операторы END своим группам?

8. Существуют ли решения, подразумеваемые по умолчанию? Например, пусть ожидается, что входной параметр X принимает значения 1, 2 или 3. Логично ли тогда предположить, что он должен быть равен 3, если он не равен 1 или 2? Например, рассмотрим программу на языке Си:

switch(X)

{

case 1: printf(“1!!!”); break;

case 2: printf(“2!!!”); break;

default: printf(“3!!!”);

}

Коль скоро это так, то является ли предположение правильным?