Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Практикум по основам программирования. Язык Паскаль

.pdf
Скачиваний:
2
Добавлен:
12.11.2023
Размер:
6.27 Mб
Скачать

Г Л А В А 10

ОТЛАДКА ПРОГРАММ

Решение задачи на ЭВМ начинается с разработки алго­ ритма. Алгоритм детализируется до уровня, который по­ зволяет написать программу на языке, выбранном для программирования. Прежде чем приступать к програм­ мированию, следует убедиться в работоспособности ал­ горитма, для чего необходимо выполнить по нему вы­ числения для некоторых исходных данных вручную. По­ сле этого можно записать алгоритм на языке програм­ мирования.

10.1 ТИПЫ ОШИБОК

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

Синтаксические ошибки выявляются на этапе трансляции. По диагностическим сообщениям трансля­ тора программист вносит соответствующие изменения в программу и повторно транслирует ее. Этот процесс повторяется до получения синтаксически правильной программы.

Для обнаружения логических ошибок нет фор­ мального аппарата, поэтому широко применяется ме­ тод тестов. Он заключается в том, что на машине про­ грамма выполняется не для тех исходных данных, Для которых надо получить результат, а для специаль­ но разработанных вариантов исходных данных с изве­ стными ответами, называемых тестами. Результаты, полученные на машине, сравниваются с правильными ответами. Их несовпадение свидетельствует о наличии

впрограмме логических ошибок.

10.2.СИНТАКСИЧЕСКАЯ ОТЛАДКА ПРОГРАММ

Вопрос отладки синтаксиса рассмотрим на приме­

ре отладки

программы решения

уравнения

вида

ах + Ьх + с - 0,

ще а,

Ь, с - любые

вещественные

числа.

Алгоритм решения

представим

в

виде блок-схемы

(Рис. ю.1).

 

 

 

 

 

Для иллюстрации процесса отладки приведем про­ грамму KW, которая содержит как синтаксические, так и логические ошибки:

PROGRAM KW<INPUT,OUTPUT);

VAR А ,В ,С ,X1,D:REAL;

BEGIN

WRIТЕ('=>*)| READLN<A ,В ,C);

IF A O 0

THEN

BEGIN

 

 

 

Ds =B*B-4*A*C;

 

 

IF D<0 THEN WRITELN('НЕТ РЕШЕНИЯ, D<0>;

 

 

ELSE

BEGIN

 

 

 

Xl:«(-B-*-SQRT(D> )/ <2*A> ;

 

 

 

X2:«(-B-SQRT(D>)/(2*A>;

 

 

 

WRITELN<*X1= ',X1:6«2, X2-*,X2:6:2>

 

 

END |

END

IF B<>0

THEN

 

WRITELN <'X-’, -C/B:6J2>

 

ELSE

IP C O 0 THEN WRI TELN ( НЕТ РЕШЕНИЯ ’)

 

 

ELSE

WRITELN(‘Б/М РЕШЕНИЙ*)

END.

После работы транслятора с языка ПАСКАЛЬ в ОС РАФОС получается следующий листинг:

RASCAL/RAFOS

SM-3/SM—4 MINICOMPUTERS PROGRAM KW <INPUT,OUTPUT);

VAR A ,В,С ,X1,D:REAL; BEGIN

WRITE('*>’); READLN(AVBVC)| IF A O 0 THEN BEGIN

Di-B*B-4*A*C;

IF D<0 THEN WRITELN <•'НЕТ РЕШЕНИЯ, D<0 *)| ELSE BEGIN

 

INVALID SYMBOL

X1:e (-B+SQRT(D))/<2«A> j

 

ALL CHARACTERS

~i

 

IGNORED UNTIL SEMI-GOLON

 

 

 

X2:- (-B-SQRT(D))/<2*A> ;

••«*«* UNDEFINED SYMBOL

*••*•« ALL CHARACTERS

IGNORED UNTIL SEMI-GOLON

 

 

 

WRITELN<'XIs *,XIs6:2, X2-',X2I6I2)

 

 

 

“i ~i

****** UNDEFINED OPERAND— ASSUMING INTEGER

******

EXPECTED

’)' MISSING. ASSUMED WHERE INDICATED

******

INVALID SYMBOL

END

 

 

 

****** ALL C H A R A C T E R S

IGNORED UN T I L END

 

 

 

ENDi

****** MISSING

AT PROGRAM END

ERRORS DETECTED:

6

 

При обнаружении ошибки в процессе трансляции компилятор отмечает синтаксически неверную строку несколькими знаками * в левой части листинга, за ко­ торыми следует пояснительный текст. Значком отме­ чается ошибочное место в строке. Грубые ошибки, на­ пример в блочной структуре программы, вызывают ряд (цепочку) других ошибок, при этом исправление первой ошибки приводит к "исчезновению" и всех ос­ тальных. Общее число ошибок, обнаруженных во вре­ мя трансляции, распечатывается в конце листинга. Пе­ речень основных ошибок, диагностика которых выдает­ ся транслятором с языка ПАСКАЛЬ в ОС РАФОС, приведен в приложении П. 3.

В программе KW транслятор обнаружил следую­ щие синтаксические ошибки:

1. Перед служебным словом ELSE стоит точка с запя­ той, что недопустимо. Транслятор указывает, что все характеристики программы игнорируются до следую­

щей точки с запятой, поэтому служебное слово BEGIN, стоящее за ELSE, не воспринимается.

2. Переменная Х2 не определена, из-за чего в двух операторах, содержащих эту переменную, отмечаются ошибки.

3. Транслятор присвоил неопределенному операнду Х2 целый тип и потребовал в связи с этим вместо симво­ ла закрывающую скобку.

4. Нарушено соответствие между числом открывающих и закрывающих операторных скобок из-за того, что не было воспринято служебные слово BEGIN. Это привело к тому, что конец программы был проигнори­ рован. Последняя закрывающая операторная скобка END, воспринятая транслятором, закрыла раздел опе­ раторов, и транслятор потребовал после него точку вместо точки с запятой.

В соответствии с полученной диагностикой про­ грамму необходимо изменить следующим образом: в разделе переменных описать переменную вещественно­ го типа Х2 и удалить точку с запятой перед ELSE. После этого программу KW следует повторно оттранс­ лировать. Получив сообщение

ERRORS DETECTED: О

можно начинать тестовую отладку программы.

10.3. ЛОГИЧЕСКАЯ ОТЛАДКА ПРОГРАММЫ

Логическая отладка программ осуществляется с помощью тестов. Тестирование простых программ, не содержащих разветвлений, не вызывает трудностей. Однако и в этом случае тест должен быть содержа­ тельным. Например, требуется вычислить значение у, если у = к[х + 5.1*2 - 1 х +4) + Г/Ос). Выбор тестовых зна­ чений к=0 и 2=0 не позволит убедиться в правильно­ сти вычисления выражения.

Для программ, содержащих разветвления, как пра­ вило, составляется несколько тестов, каждый из кото­ рых проверяет соответствующую ветвь программы. Рассмотрим процесс тестовой отладки приведенной вы­ ше программы KW. Число тестов (5) определяется ко­

личеством

ветвей в ней.

Т е с т

1. Проверяется ветвь а - 0; Ь2 - 4ас^0; для

этого выбираются следующие значения коэффициен­ тов: я=1, Ь=1, с=-б.

Ожидаемый ответ: X I=2.00 Х2=-3.00.

Т е с т 2. Проверяется ветвь а - 0; 62 - 4ас<0, для это­

го выбираются следующие

значения

коэффициентов:

а-1, 6= 1, с=6.

 

 

Ожидаемый ответ: НЕТ РЕШЕНИЯ, D<0.

Т е с т 3. Проверяется

ветвь а=0;

6=0, для этого

выбираются следующие значения коэффициентов: а=0, 6=2, с=8.

Ожидаемый ответ: Х=-4.00.

Т е с т 4. Проверяется ветвь а=0; 6=0; с=0, для этого выбираются следующие значения коэффициен­ тов: а=0, 6=0, с=8.

Ожидаемый ответ: НЕТ РЕШЕНИЯ.

Т е с т 5. Проверяется ветвь а=0; 6=0; с=0, для этого выбираются следующие значения коэффициен­ тов: а=0, 6=0, с=0.

Ожидаемый ответ: Б/М РЕШЕНИЙ.

Выполним программу для каждого из тестовых наборов исходных данных. Результат выполнения по тесту 1 следующий:

XI = 2.00 Х2=-3.00 Х= 6.00

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

Так как

А =2.0, т. е.

А < >0, выполняется следующий

составной

оператор:

IF А о О THEN BEGIN... END.

Согласно блок-схеме алгоритма, после вычисления дис­ криминанта, его анализа и печати результата управле­ ние должно быть передано на конец программы. В программе же вместо условного оператора вида IF В THEN SI ELSE S2 использована конструкция вида IF В THEN S1. При этом В < > 0 и выполняется еще один оператор WRITELN(’X=’, - С/В:6:2), который и приво­ дит к печати строки Х=6.00. Следовательно, программу необходимо откорректировать следующим образом: пе­ ред условным оператором IF В <>0... вместо точки с запятой поставить служебное слово ELSE.

Исправленную программу следует выполнить еще раз для набора исходных данных теста 1. После полу­ чения ожидаемого результата проверяются остальные ветви. Если вычисления по остальным тестам дают правильные ответы, то можно сделать вывод, что в от­ лаживаемой программе KW полностью отсутствуют

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

Приведем откорректированный текст программы

KW:

PROGRAM КМ(INPUT fOUTPUT); VAR А,В,С,XI, X2,D:REAL; BEGIN

WRITE<•=>•>; READLN(A,B,C>; IF A< >0 THEN BEGIN

D:=B*B-4*A*C;

IF D<0 THEN MRITELNCHET РЕШЕНИЯ, D<0*> ELSE BEGIN

X1:= <—B+SQRT <D) )/<2*A) 5

X2:* (-B-SQRT(D))/<2*A>|

MRITELN < XI-',XI:6 1 2, X2-*,X2«6i2> END

END

ELSE IF BO 0 THEN MRITELN<*X=*, -C/B:6:2)

ELSE IF C O B THEN MRITELN (НЕТ РЕШЕНИЯ ') ELSE MRITELN(*Б/М РЕШЕНИИ')

Реальные программы настолько сложны, что про­ вести их полную проверку по всем ветвям с помощью тестов практически невозможно. Как правило, тесты проверяют наиболее вероятные участки программы.

Глава 1

5. Неправильно записаны п. а), г), д), и), л), м). 6. а) 5; б) - 5; в) 17; г) 18; д) -17; е) -18.

7.Неправильно записаны п. а), г), д).

8.а) 49; б) *; в) А; г) С.

10.Правильно записаны п. aV б), в), е).

13.Правильно записаны п. а), б).

15.а) (А< =0) OR (А> =3);

б) (А >= -2 )

AND (А< =0);

в)

((А> = -5 )

AND (А< = - 4)) OR ((А> =0) AND (A <=2))O R

 

((А> =3.2 AND (А < =7»;

г) X»X+Y*Y <2.3*2.3;

д) X*X+Y*Y > =1.

17. а)

А2 1.600000Е+01;

б)

TRUE

TRUE

 

КОНЕЦ

в) 16.0 РЕЗУЛЬТАТ

PROGRAM W<OUTPUT):

BEGIN

 

 

WRITELN( ЗНАЧЕНИЕ ВЫРАЖЕНИЯ РАВНО *);

 

WRI TELN <(5. 23+SQR (7.6) 4-SIN (3. 14159/7) )/

 

(SIN(2*3.14159//)+3.1))

END.

 

Глава 2

2. б) Перед ELSE стоит точка с запятой, что недопу­

стимо.

и THEN стоит

г)

Между служебными словами IF

выражение не булевского типа,

булевского типа,

е)

Переменная Р должна быть

чтобы правильно вычислялось условное выражение; следовательно, оператор присваивания P:=P+10w5 недо­ пустим.

A)IF Х<Y THEN X:=0

 

 

ELSE IF

X >Y THEN Ys=0

 

Y:=0 END;

6.

 

 

 

ELSE BEGIN X:=0;

 

 

 

 

 

 

PROGRAM W X (INPUTtOUTPUT);

 

 

VAR X fY :REAL;

 

 

 

 

BEGIN

READLN(X);

 

 

 

 

IF

X<0

THEN Ys=X*X+l

 

 

 

 

ELSE IF

X>3.14159/2 THEN Ys*X-2.1

WRITELN('Y = ',Y s8 s4)

ELSE Ys=SIN<X>;

 

 

 

END.

 

 

 

 

 

 

7.

 

 

 

 

 

 

PROGRAM Y P (INPUT,OUTPUT);

 

 

VAR

A,B,C,TsINTEGER;

 

 

BEGIN READLN(А,В,C);

A:=B;

Bs=T END;

 

IF

A<B THEN

BEGIN Ts=A;

 

IF

B<C THEN

BEGIN T:=C;

Cs=B;

Bs*T END;

 

IF

A<B THEN

BEGIN T:=A;

As=B;

Bs=T END;

END.

WRITELN<As4,Bs4,Cs4)

 

 

 

 

 

 

 

 

10.

 

 

 

 

 

 

a) PROGRAM

GORNER1 СINPUT,OUTPUT);

 

VAR

NaINTEGER;

Y fAsREAL;

 

 

BEGIN READLN(A);

 

 

 

 

Ys~A+2;

TO

8 DO Y:=Y*A+N;

 

 

FOR Ns =3

 

WRI TELN ('Y= 'tYs 8s 4)

END.

6)

PROGRAM GORNER2(INPUT,OUTPUT);

VAR Ns INTEGER; Y ,As REAL;

BEGIN READLN(A);

Ys*8*A+7;

FOR Ns=6 DOWNTO 1 DO Ys-Y*A+N;

WRITELN(*Y = *fYs 8s 4)

END.

1L

PROGRAM KO L(IN PU T,O U TPU T) ;

VAR K VL , I s IN TEG ER; As CHAR;

BEGIN

K i - 0 | L s * 0 |

 

 

 

 

FOR I s « l

TO

30 DO

 

 

 

BEGIN

REA D (A )|

 

 

 

 

IF

A - ' A *

THEN

K i> K + l

 

 

 

 

E L S E

I F A* 'B * THEN

L s= L -H ;

END;

 

 

 

 

 

READLN;

 

 

 

 

 

W RITELN< СИМВОЛОВ

A - ' , K t 2 , # СИМВОЛОВ

B - ' , L : 2 >

END.

PROGRAM EX(INPUT,OUTPUT)|

CONST E—0.IE—3;

VAR X,Y ,SL:REAL;

Ns INTEGER;

BEGIN

SLs=l;

Y:=0; Ns=l;

READLN(X);

WHILE ABS(SL)>E DO

BEGIN Ys=Y+SL| SLs=SL*X/N; N:=N-»-l END; WRITELN('ПРИ X= *,X:8:4,' Y«*,Yses4>

END.

Глава 3

4. В разделе констант для константы А необходимо указать конкретное значение, а не диапазон значений; знак присваивания недопустим, а при записи вещест­ венной константы нельзя использовать запятую. При задании ограниченного типа нельзя диапазон значений заключать в скобки. Разделителем между именами при определении перечислимого типа является запятая, а не точка с запятой. В качестве объектов при задании перечислимых типов можно использовать только име*- на; цифры и символьные значения недопустимы.

6.Неправильными являются операторы присваивания

вп. б) и г) из-за несоответствия типов правой и левой частей.

CASE

I OF

ШУРУП *>;

Is

WRITELN(

2s

WRITELN(

ГАЙКА*);

3:

WRITELN(

ВИНТ *>;

4 s WRITELN(

ШПИЛЬКА *>

END;

 

 

О

 

 

READ (I);

 

CASE

I OF

 

1:

ТЕКСТ:=ЛЕТО;

2s

ТЕКСТs»OCEHb;

3:

ТЕКСТ s=ЗИМА;

4s

ТЕКСТs=BECHA

END;

 

 

10. В операторе READ указано имя M переменной ог­ раниченного типа, для которого базовым является пе­ речислимый тип МЕСЯЦ. Вводить значения перечис­ лимого типа нельзя. В операторе присваивания D:=K нет соответствия типов. В операторе WR1TELN недопу­ стимым является выражение D+K, так как операция

сложения между переменными символьного и целого типов не определена.

13.Будет напечатано К=4М.

14.Нет соответствия между типом селектора INTEGER

итипом меток CHAR.

17.

PROGRAM VARI(INPUT,OUTPUT)|

VAR SICHARJ K1,K2,K3iINTEGERj

BE6IN READLNi WRITE<->),

K1J=0J K2*-0| K3«-0|

REPEAT READ(S)|

CASE S OF

’•'« ;

*A ‘i Kls«Kl+l| *B*i K2J"K2+1| *C*« K3i-K3+i

END UNTIL S-'. *

NRITELNI БУКВ A— *(К1121 БУКВ B-*tK2«2f* БУКВ C-*,K3i2>

END.

Глава 4

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

3.

FOR I:= *К ' ТО *Z ’ DO АС13:=0;

PROGRAM W M A S (INPUT ,OUTPUT);

VAR A:PACKED ARRAYC-5..53 OF CHAR; I:-5..3|

BEGIN READLN; WRITE<*=>*>;

FOR I:=-5 TO 5 DO READ(АС I3);

READLN;

WRITELN(A)

END.

5.Неправильными являются описания в п. г) и е).

6.а) 12; б) 10; в) 16.

7.б) Второй индекс превышает допустимое значение,

г) Имеется несоответствие типов индексов.

е) Первый индекс должен быть также перечисли­ мого типа.

FOR J:*P0H6 ТО ТРАПЕЦИЯ DO READ(АС I,JЭ)J

11.Неправильными являются операторы присваивания

вп. а) и д).