- •Тема_3: Розширені можливості підпрограм (продовження)
- •1. Рекурсивні підпрограми.
- •Форми рекурсивних підпрограм.
- •If умова Then Rec;
- •If умова Then Rec;
- •Виконання дій при рекурсивному запуску
- •Виконання дій на рекурсивному повернені
- •Виконання дій як при рекурсивному спуску, так і при повернені
- •2. Випереджувальне оголошення підпрограм.
- •3. Процедурний тип даних.
- •4. Побічні ефекти при використанні підпрограм.
2. Випереджувальне оголошення підпрограм.
Рекурсивне звернення до підпрограми може бути не прямим, тобто, коли підпрограма звертається до себе шляхом звернення до іншої п/п, яка містить у собі звернення до першої п/п. ( А В). Дані п/п слід оголосити таким чином:
Procedure B (j: byte);
Forward ;{ Замість тіла процедури}
Procedure A (i: byte);
Begin …
B (i);
…
End;
Procedure B; {Параметри не вказують}
Begin …
A (j);
…
End;
3. Процедурний тип даних.
Змінній процедурного типу можна присвоювати ім’я процедури та використовувати у подальшому цю змінну для виклику процедури.
Приклад.
Program Proc_type;
Type proc= procedure (var m1, m2: byte);
Var x, y: byte; p1: proc;
{$f+} {директива, яка задає можливість використання процедурного типу даних}
{-----------------------------------------------}
Procedure swap (var a, b: byte);
Var temp: byte;
Begin
Temp: = a; a: =b; b: =temp
End; {swap}
{----------------------------------------------}
Procedure sum (var k1, k2: byte);
Begin
If k1>k2 then k1:=k1+k2
End; {sum}
{--------------------------------------------}
{$f-} {відміна дії директиви}
Begin write (‘’); readln (x, y);
P1:= swap; p1(x, y);
Writeln (‘x=’, x, ‘ y=’, y);
P1:= sum; p1(x, y);
Writeln (‘x=’, x, ‘ y=’, y)
End.
4. Побічні ефекти при використанні підпрограм.
Якщо в тілі функції змінюються значення глобальних змінних або ж параметрів-змінних, то кажуть, що функція має побічний ефект. Їх потрібно уникати.
Приклад. Ситуація1 – зміна глобального параметра.
Нехай функція f(x) має вигляд:
Function f(x: real): real;
Begin
V: =v*x;
F: = sqrt (v) +x
End;
Ця функція змінює значення глобальної змінної V.
В основній програмі оператори write(f(x), v) та write(v, f (x)) роздрукують різні значення.
Приклад. Ситуація2 – використання параметрів змінних.
Обчислити п’ятий член послідовності, утворений за законом: а1= 1; аn+1= 4аn-2
Якщо оформити функцію у вигляді
Function f (var a, n: integer): integer;
Var i: integer;
Begin
For i: =1 to n do a: = 4*a-2;
F: = a
End;
то при зверненні до неї за допомогою оператора b:= f (1,5) буде змінений параметр a, тобто 1, через те що в комірку пам’яті, в якій була ця 1 функція f помістить поточний член послідовності і при подальших обчисленнях замість 1 буде використовуватись значення а5.
Висновок. Такі помилки тяжко виявляти, це логічні помилки. Щоб їх уникнути, потрібно дотримуватись правил:
не використовувати глобальних змінних;
не використовувати у функціях параметрів-змінних.
Зауваження. Можна достроково вийти з п/п за допомогою оператора EXIT.