книги / Практикум по основам программирования. Язык Паскаль
.pdfГ Л А В А 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.Неправильными являются операторы присваивания
вп. а) и д).