Параметри

Параметри процедур та функцій можуть мати довільний тип, включаючи структурований. Pascal використовує два різних види параметрів в процедурах і функціях: параметри-значення та параметри-змінні.

Коли параметри передаються як значення, він використовується в виді змінної, локальної в блоці, яким є процедура або функція. Для локальної змінної виділяється спеціальний фрагмент пам'яті, який має стекову організацію. При передачі в процедуру або функцію фактичні параметри копіюються в відповідні їм локальні змінні. Основною перевагою передачі параметрів-значень є те, що зміна значень формальних параметрів в процедурах та функціях не призводить до зміри відповідніх їм фактічних змінних в основній програмі.

При передачі параметра-змінної фактичний параметр завди повинен бути змінною. На час виконання процедури або функції фактичний параметр замінює формальний. Замість копіювання значень, в блок передаються адреси комірок памяті, де розміщуються фактичні параметри (змінні). Надалі будь-яка дія над формальним параметром-змінною в дійсності виконується над відповідним фактичним параметром. Параметри-змінні використовуються при передачі в підпрограми великих масивів інформації, що дозволяє уникати обтяжливого копіювання, а також в тих випадках, коли необхідно передати результат з підпрограми в основну програму.

Тип в секції формальних параметрів повинен бути або стандартним, або попередньо означеним.

Приклад:

Запис Procedure Ost(i: Array[1..12] of Real); – помилковий.

Правильний запис: Type MAS = Array[1..12] of Real;

Procedure Ost(i: MAS);

Ознакою того, що параметр передається як змінна, є наявність службового слова VAR перед ідентифікатором.

Приклад:

Type MAS = array[1..12] of real;

Procedure Ost(Var i: MAS);

 

9.1.4. Рекурсивні підпрограми

В тілі підпрограми допустимі всі об'єкти які описані в глобальному описовому блоці, зокрема і ім’я самої підпрограми. Таким чином, всередині тіла підпрограми можливий виклик самої підпрограми. Процедури і функції, що використовують виклик "самих себе", називаються рекурсивними. Допустима також непряма рекурсія, при яких, наприклад, процедура A викликає процедуру B, а та, в свою чергу викликає С, яка викликає A.

Рекурсія досить широко використовується в програмуванні, що обумовлено рекурсивною природою багатьох математичних алгоритмів.

Як приклад, розглянемо програма обчислення факторіала N!. Очевидно: 0!=1; 1!=1; N!=1*2*...(N-1)*N; N!=(N-1)!*N. Ці відношення реалізуємо такою функцією:

Function Fact(N: Іnteger): Real;

Begin

If N=0 then Fact:=1.0

else Fact:=N*Fact(N-1)

End;

В мові Pascal немає ніяких обмежень на рекурсивні виклики підпрограм; необхідно лише мати на увазі, що кожний новий рекурсивний призводить до утворення копії локальних об'єктів підпрограми і всі ці копії не закінчених рекурсивних викликів існують незалежно один від другого. При написанні рекурсивних підпрограм необхідно звертати особливу увагу на вихід з підпрограми в потрібний момент, так як можливий вихід значень з допустимого діапазона або втрата порядку (результат обертається в нуль). Наприклад, в Turbo Pascal 3.0 для рекурсивна процедура може викликати сама себе не більше ніж 430 разів.

При реалізації алгоритмів з непрямою рекурсією використовується спеціальна деректива попереднього опису процедури Forward. Попередній опис складається з заголовку процедури і службового слова Forward.

Приклад:

Procedure Korrect; Forward;

Function Nalog (Z : real) : Real; Forward;

Далі процедура описується без повторення списку формальних параметрів.

Приклад:

Var A: Integer;

Procedure P1 (t: Real;);

Begin

P2; {Виклик не визначеної процедури}

End;

Procedure P2(V: Real);

Begin

P1;

End.

В даному прикладі виклик процедури P2 здійснюється до того, як вона описана, що є помилкою.

Правильна програма:

Var a : Integer;

Procedure P2 (v : Real;); Forward;

Procedure P1 (t : Real);

Begin

P1;

End;

Procedure P2; {список формальних параметрів не повторюється}

Begin

P1;

End.

9.1.5. Область дії ідентифікаторів

Pascal - програма має модульну структуру і може складатися з ряду вкладених блоків. Основна програма – самий великий блок, що не входить в інші. Об'єкти описані в цьому блоці є глобальними і можуть використовуватися в усіх локальних блоках. Локальні блоки – це процедури і функції користувача. Описані в них об'єкти є локальними і недоступні в зовнішніх блоках.

Правила користування ідентифікаторами Pascal-програми:

Кожний ідентифікатор повинен описуватися перед використанням.

1. Областю дії ідентифікатора є блок, в якому він описаний.

2. Всі ідентифікатори в блоці повинні бути унікальними, тобто не повторюватися.

3. Один і той же ідентифікатор може по різному бути визначеним в кожному окремому блоку.

4. Якщо ідентифікатор підпрограми користувача співпадає з іменем стандартної процедури або функції, то вони ігноруються а виконується підпрограма користувача.

Однією з поширених помилок програміста є випадкове використання глобальних змінних в процедурах і функціях, де вони змінюють своє значення. Це може призвести до прикрих несподіванок.

Приклад:

Дано дійсні p, q.

Обчислити

де

Текст програми 1

program fun;

var z,p,q:real;

function k(x,y:real):real;

begin

k:=x/(1+sqr(sin(y)))+y/(1+sqr(x));

end;

begin

readln(p);

readln(q);

z:=(k(1+p*q,sqr(q))+sqr(k(p,sqr(p))))/(1+k(p*q+sqr(q),p));

writeln('z=',z);

readln;

end.

Результат виконання програми

z=1.5259865321E+00

Текст програми 2

program pros;

var y,y1,z1,y2,z,p,q:real;

procedure k(x,y:real;var z1:real);

begin

z1:=x/(1+sqr(sin(y)))+y/(1+sqr(x));

end;

begin

readln(p);

readln(q);

k(1+(p*q),sqr(q),y);

k(p,sqr(p),y1);

k(p*q+sqr(q),p,y2);

z:=(y+sqr(y1))/(1+y2);

writeln('z=',z);

readln;

end.

Результат виконання програми

z=1.5259865321E+00