Rambler's Top100

Скачать программы    Все программы автора

ЛАБОРАТОРНАЯ РАБОТА 8

СТИЛЬ ПРОГРАММИРОВАНИЯ НА ЯЗЫКЕ PASCAL

 Цель работы: познакомить с понятием "хороший стиль" программирования на языке Pascal и выработать практические навыки "хорошего стиля" программирования в системе TURBO Pascal.

 

ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

 

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

Оператор GoTo

В языке Pascal принят естественный порядок выполнения программы: все операторы выполняются последовательно один за другим в том порядке, как они записаны. Однако в практике программирования возникает необходимость нарушения последовательности выполнения операторов (например, необходимо "обойти" участок программы, а вернуться к нему позже). Для этого предназначен оператор перехода  GoTo. Данный оператор служит для передачи управления из одной точки программы в другую. В некоторых случаях он весьма полезен, но в то же время этот оператор затрудняет восприятие программы (имеется в виду восприятие программы человеком, так как для компьютера обработка операторов GoTo труда не составляет). Отслеживание этого оператора напоминает ситуацию, в какой Вы оказались бы, если бы при чтении романа Вам приходилось все время перелистывать книгу на несколько страниц то назад, то вперед. Прерывая логическую последовательность чтения, операторы GoTo практически исключают возможность хорошо разобраться в структуре программы для всех, кроме ее автора. А это в свою очередь не позволяет делать в программе какие-либо изменения без риска внести ошибки в самые неожиданные ее части.

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

Конечно, написать программу-спагетти на языке Pascal можно и без оператора GoTo, если, например, необдуманно применить глобальные переменные, неосторожно использовать указатели, упустить из виду побочное действие функций. Все эти опасные моменты гораздо хуже, чем GoTo, так как глобальные переменные, указатели и процедуры могут быть необходимы нам для полезных целей и обойтись без них бывает очень трудно.

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

GoTo < Метка >
где:

1) GoTo ("идти к") - служебное слово;
2)  Метка  - целое число без знака в диапазоне [1,9999]. Более того, в диалекте TURBO Pascal разрешено использовать в качестве меток идентификаторы.

Метка записывается перед помечаемым оператором и отделяется от него двоеточием. Например:

GoTo 32;

10: a:=2;

...

32: y:=x/z

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

Метка должна быть объявлена в разделе описания label.

Объявление меток имеет вид:

label Метка1,Метка2,...,МеткаN;

Например, для рассмотренного выше фрагмента программы объявление меток выглядит следующим образом:

label 10,32;

 Замечания.

1. Если необходимо пропустить несколько операторов в составном операторе, но не выходить из него, то перед зарезервированным словом end ставится метка и двоеточие, например:

...

lab: end;

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

...

lab:

end.

 

Процедура Break

Процедура  Break позволяет выйти из операторов цикла For, While, Repeat без проверки условия.

Вызов процедуры Break приводит к немедленному выходу из самого внутреннего охватывающего его цикла. Управление передается оператору, следующему за заканчиваемым оператором. Одно из назначений вызова этой процедуры - закончить выполнение цикла при присвоении некоторой переменной определенного значения.

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

Пример 1.

PROGRAM Primer1;

var x,y,z: Integer;

BEGIN

x := 1;

WriteLn ('Мы будем вычислять значение функции y=2*x+z');

WriteLn ('Введите значение z: '); ReadLn (z);

While x<100 do

begin

y := 2*x+z; x:=x+1;

If y=50

then begin WriteLn ('y = 50'); Break end;

end;

If y=50 then WriteLn ('Цикл закончен!')

else WriteLn ('Цикл закончен! Но y<>50.');

END.

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

Пример 2.

Видоизмененная программа из примера 1.

PROGRAM Primer2;

var x,y,z: Integer;

BEGIN

x := 1;

WriteLn ('Мы будем вычислять значение функции y=2*x+z');

WriteLn ('Введите значение z:'); ReadLn (z);

While (x<100) AND (y<>50) do

begin

y := 2*x+z; x := x+1

end;

If y=50 then WriteLn ('Цикл закончен!!!')

else WriteLn ('Цикл закончен!!! Но y<>50.')

END.

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

While TRUE do

begin

...

end,

а выход из цикла оформить с помощью вызовов процедуры Break.

 

Процедура Continue

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

Пример.

PROGRAM Primer;

var x,y,z: Integer;

BEGIN

WriteLn ('Мы будем вычислять значение функции y=2*x+z');

WriteLn ('в промежутках [1,6] и [13,18).');

Write ('Введите значение z='); ReadLn(z);

For x:=1 to 17 do

begin

If (x>6) AND (x<13) then Continue;

y := 2*x+z;

WriteLn ('x=',x,' y=',y)

end

END.

Если x принадлежит промежутку [7,12], то "оставшаяся" часть итерации пропускается и происходит переход к началу следующей.

 

Тестирование и отладка программ

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

 Правила тестирования :

- должна быть испытана каждая "ветвь" программы;

- очередной тест должен контролировать то, что еще не было проверено на предыдущих тестах;

- первый тест должен быть максимально прост;

- возникающие затруднения следует четко разделять и устранять строго поочередно;

- количество проходов цикла должно быть временно уменьшено для сокращения объема вычислений;

- тесты должны быть целенаправленными и систематизированными;

- усложнение тестовых данных должно быть постепенное.

 Этапы тестирования.

1.Проверка  нормальных условий. Тестирование на основе данных, характерных для реальных условий функционирования программы.

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

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

Таким образом, тестирование устанавливает факт наличия ошибки. Отладка объясняет его причину.

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

(1) синтаксические ошибки  - вызов команды, не входящей в систему команд конкретного языка программирования, обычно их обнаруживает компилятор или интерпретатор данного языка программирования;

(2) семантические ошибки  - вызов команды в ситуации, когда эта команда не может быть исполнена, эти ошибки приводят к отказу компилятора или интерпретатора работать;

(3) логические ошибки  - ЭВМ выполнила программу, но цель, поставленная человеком, не достигнута. Эти ошибки не фиксируются ни ЭВМ, ни компилятором или интерпретатором, важно понимать, что "безотказное" выполнение программы еще не означает его правильность.

 Контроль  правильности написанной программы состоит, как правило, из трех этапов:

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

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

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

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

Пример.

 Составить систему тестов для задачи нахождения корней квадратного  уравнения: $ax^2+bx+c=0.$

1) a=1, b=1, c=-2. Хороший начальный тест.

2) a=1, b=0, c=0.25. Проверка в нормальных условиях.

3) a=0, b=0, c=0. Что произойдет?

4) a=0, b=2, c=1. Должен быть один корень.

5) a=2, b=1, c=0. Все должно быть в порядке.

6) a=1, b=1, c=1. Вещественных корней нет.

7) a=0, b=0, c=2. Неправильное уравнение.

8) a=0, b=2, c=0. Должен быть один корень.

9) a=2, b=0, c=0. Должно быть два одинаковых корня.

10) a=1, b=0, c=4. Должно быть два одинаковых корня.

ЗАДАЧИ ДЛЯ САМОСТОЯТЕЛЬНОГО РЕШЕНИЯ

 

1."Причесать" процедуру или функцию.

1.1.

PROCEDURE E_n_t_e_r (var T: Ref); { Построение произвольного бинарного

дерева } var X: TipElement; BEGIN Read (X); If X='.' then T:=Nil else

begin New (T); T^.Key:=X; T^.Count:=1; E_n_t_e_r (T^.Left); E_n_t_e_r

(T^.Right) end END;

 

1.2.

PROCEDURE P_r_i_n_t_T_r_e_e (w: Ref; l: Integer); { Вывод дерева на экран

дисплея } var i: Integer; BEGIN If w<>Nil then begin P_r_i_n_t_T_r_e_e

(w^.Right,l+1); For i:=1 to l do Write (' '); WriteLn (w^.Key);

P_r_i_n_t_T_r_e_e (w^.Left,l+1) end END;

 

1.3.

PROCEDURE S_e_a_r_c_h (X: Integer; var p: Ref); { Поиск узла с

информационным полем X в бинарном дереве, } { заданном указателем p с

последующей вставкой в дерево } BEGIN If p=Nil then begin New (p);

p^.Key:=X; p^.Count:=1; p^.Left:=Nil; p^.Right:=Nil end else If X<p^.Key

then S_e_a_r_c_h (X,p^.Left) else If X>p^.Key then S_e_a_r_c_h

(X,p^.Right) else p^.Count:=p^.Count+1 END;

 

1.4.

FUNCTION P_o_i_s_k_v_d_e_r (k: Integer; d: Ref; var Res: Ref): Boolean;

var p: Ref; b: Boolean; BEGIN b:=FALSE; p:=d; If d<>Nil then Repeat If

p^.Key=k then b:=TRUE else If k<p^.Key then p:=p^.Left else p:=p^.Right

until b OR (p=Nil); P_o_i_s_k_v_d_e_r:=b; Res:=p END;

 

1.5.

PROCEDURE U_d_a_l_d_r (var d:Ref;k:Integer); { Удаление узла с ключом k из

дерева d } var q:Ref; { ------------------------ } PROCEDURE U_d(var r:Ref

); BEGIN If r^.Right=Nil then begin q^.Key:=r^.Key; q^.Count := r^.Count;

q:=r; r:=r^.Left; Dispose (q) end else U_d (r^.Right) END;

 

2. "Причесать" программу, выяснить, что она делает, произвести   замену имен, внести комментарии

2.1.

program a; var a1, a2: integer; function a3 (a4, a5: integer) :

integer;begin if a4=a5 then a3:=a4 else if a4<a5 then a3:=a3 (

a4,a5-a4) else a3:=a3(a5,a4-a5) end;begin readln(a1,a2); if (a1>

0)and(a2>0) then writeln (a1 div a3(a1,a2),' ',a2 div a3(a1,a2))

end.

 

2.2.

program x;var x11,x1, x3,x8,x1995:integer;

begin for x11:=1 to 99 do begin

x8:=x11*x11; x1:=x11 div 10;

x3:=x11-x1*10;

x1995:=x1+x3; x1995:=x1995* x1995

*x1995;if x1995=x8 then writeln(x11) end

end.

 

2.3.

program k ; var i,d,f,x,y,n,p :integer ;begin for i:=1 to 99

do begin y:=i*i; d:=i div 10; f:=i-d*10 ; n:=d*d+f*f;p:=n div

13; if n=p * 13 then writeln('Число: ' , i ) end end .

 

2.4.

program a;var aa, aaa,aaaa,aaaaa,aaaaaa:integer; function aaaaaaa

(t : integer ) : boolean; begin aaaaaaa := t mod 2=1 end ; begin

readln ( aaaa ) ; readln (aaaaa); aa:= aaaa;aaa:=aaaaa;aaaaaa:=1;

while aaa<>0 do if aaaaaaa(aaa) then begin aaaaaa := aaaaaa*aa;

aaa:= aaa - 1 end else begin aa:=aa*aa;aaa:=aaa div 2 end;writeln

( aaaaaa ) end .

 

2.5.

program a; var n:integer;function i(n:integer):integer;begin if n>1 then

i := n * i(n-1) else i:=1 end; begin readln (n); writeln (i ( n ) ) end.

 

2.6.

program z ; var x, y :

integer; function o (m,n:integer): integer;

begin if n= 0 then o:=1 else o:=m*o(m,n-1)end;

begin readln(x,y); writeln ( o ( x ,y)) end.

 

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

3.1.

program x; var a:integer;

function f(n:integer):integer; var i,k:integer; label L;

begin k:=0; for i:=1 to n-1 do begin if i mod 2=0 then goto L;

if i mod 3=0 then goto L; k:=k+1;

L: ; end; f:=k end;

begin readln(a); if a>0 then writeln(f(a)) end.

 

3.2.

program a;

var x,y,z,w:integer;

function f(a,b,c,d:integer):integer;

var e,m:integer; label L1,L2;

begin e:=c; if a<b then goto L1; m:=a; goto L2; L1: m:=b; L2:;

if m>e then m:=m else m:=c; if (m>d) then else m:=d;

f:=m end; begin readln (x,y,z,w); writeln(f(x,y,z,w)) end.

 

3.3.

program a; var x,y,z

:integer

;function f(a,b,

c:integer): integer; var

m:integer;begin if (a<=b)

and(a<=c) then m:=a;if(b<=a)

and(b<=c)then m:=b;if (c<=b)

and(c<=a) then m:=c; f:=m

end; begin readln(x,y

,z) ;writeln (f

(x,y,z))

end.

 

3.4.

program a;

var x,y,z:integer; label L; begin writeln(

'Мы будем вычислять значение функции y=2*x+z');

writeln ('в промежутках [1,6] и [13,18).');

write ('Введите значение z: '); readln (z);

for x:=1 to 17 do begin if (x>6) and (x<13) then goto L;

y:=2*x+z; writeln('x =',x,' y =',y); L: end end.

 

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

4.1 4.2.

Repeat

While (A) do If (NOT A)

begin then Continue else B;

if (B) then Continue; C;

C until (A);

end;

 

4.3 4.4.

If (A) i:=0; done:=i;

then If (B) While (i<MAXI) AND (done=0) do

then If (C) begin

then D x := x DIV 2;

else If x>1

else then begin i:=i+1; continue end

else If (B) done:=done+1

then If (C) end;

then E

else F;

else;

 

4.5 4.6.

plusflg:=0; If x<>0

zeroflg:=0; then If j>k

negflg:=0; then y:=j/x

If a>0 then plusflg:=plusflg+1; else y:=k/x

If a=0 else If j>k

then zeroflg:=zeroflg+1 then y:=j/NEARZERO

else If plusflg=0 else y:=k/NEARZERO;

then negflg:=negflg+1;

 

4.7.

begin

If (A) then begin B; goto L end;

If (C) then begin D; goto L end;

If (E) then begin F; goto L end;

G; goto L

end;

L: ;

Вверх

Белорусский рейтинг MyMinsk.com Сайты беларуси Регистр "ЗУБР" Каталог на TIGA.BY, а также  новости, работа, объявления, фото и многое другое Rambler's Top100 Белорусский каталог программ Faststart - рейтинг сайтов, каталог интернет ресурсов, счетчик посещаемос­ти Яндекс.Метрика
Hosted by uCoz