Паскаль. Прикладне програмне забезпечення


ПАСКАЛЬ: точка повернення, підстановка аргументів, зберігання змінних

1. Точка повернення

Місце в програмі, що описує дію, якою вона продовжується по закінченні виконання виклику підпрограми, називається Точкою повернення з підпрограми.

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

Точка повернення з процедури – це позначення дій, виконуваних після її виклику. Це може бути наступний за її викликом оператор, як у програмі Sort31. Або умова завершення чи продовження циклу, якщо виклик записаний останнім у тілі циклу.

Після виклику функції може застосовуватися операція до значення, що повертається з виклику, або обчислюватися наступний операнд у виразі, або обчислене значення може використовуватися в операторі. Наприклад, у програмі Minimdis із підрозділу 3.3 результат виклику функції присвоюється змінної Dd. У програмі Simpi із прикладу 4.7 виклик функції Issimple записана як умова в Ifоператорі, і після виклику визначається, яка з гілок повинна бути виконана. При обчисленні виразу sqrx+sqry спочатку один за одним виконуються виклики функції sqr, потім повернуті з них значення додаються.

Конкретний вигляд точки повернення в машинній програмі ми не уточнюємо.

2. Локальна пам'ять процесу виконання виклику підпрограми

У підрозділі 3.4 ми вже говорили про те, що параметрамзначенням підпрограми при виконанні її виклику зіставляються власні ділянки пам'яті, тобто змінні. У блоці підпрограми можуть бути означені власні імена змінних – ділянки пам'яті зіставляються їм так само. Крім того, є ділянка пам'яті з точкою повернення. Сукупність усіх цих ділянок пам'яті називається Локальною пам'яттю процесу виконання виклику підпрограми. Її часто неточно називають локальною пам'яттю підпрограми. Будемо грішити цим і ми. Змінні в ній також називаються Локальними.

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

Таким чином, наприклад, локальна пам'ять процедури Swap із підрозділу 3.4 у її остаточному вигляді складається з єдиної змінної, зіставленої імені T, а пам'ять функції Dd із програми Minimdis підрозділ 3.3 – із змінних, зіставлених іменам Xx1, Yy1, Xx2, Yy2 і Dd. А також указівки на точку повернення.

3. Підстановка аргументів на місце параметрів

Перед тим, як починається виконання операторів тіла підпрограми, для неї виділяється локальна пам'ять і в ній запам'ятовується точка повернення. Потім обчислюються значення тих аргументів у виклику, які відповідають параметрамзначенням. Ці значення присвоюються локальним змінним, які поставлено у відповідність параметрамзначенням.

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

Підстановка аргументів на місце параметрівзмінних відбувається зовсім іншим шляхом. Нагадаємо, що таким аргументом може бути тільки ім'я змінної або інше її позначення, наприклад, у вигляді поля структури. Ніякого обчислення її значення, тобто розіменування аргументу, не відбувається.

Ця змінна, тобто ділянка пам'яті, ставиться у відповідність параметрові підпрограми. Це називається Підстановкою аргументу на місце параметра за посиланням, або За адресою. У результаті такої підстановки

Ім'я параметразмінної перетворюється на вказівку на ділянку пам'яті, яка поставлена у відповідність аргументу.

Вказівка на ділянку пам'яті називається Посиланням на неї, або її Адресою. Як саме вказівка на аргумент стає відомою у процесі виконання підпрограми, ми не уточнюємо. Для цього нам довелося б занадто глибоко забратися в устрій комп'ютера і машинної мови.

4. Процес виконання виклику підпрограми

Опишемо процес виконання виклику підпрограми вона називається такою, що Викликається, а програма або підпрограма, що містить її виклик – такою, що Викликає.

1. Виділяється локальна пам'ять підпрограми, що викликається, а точніше, пам'ять процесу виконання виклику.

2. Обчислюється й запам'ятовується в локальній пам'яті підпрограми, що викликається, точка повернення в ту, що викликає.

3. Обчислюються значення аргументів, відповідних параметрамзначенням, і посилання на пам'ять аргументів, відповідних параметрамзмінним. Виконується підстановка аргументів.

4. Лише після цього виконуються оператори тіла підпрограми. Зокрема, у локальній пам'яті запам'ятовується значення, що повертається з виклику функції.

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

Як уже говорилося в підрозділі 3.4, усяка зміна значення параметразмінної є насправді зміною відповідного аргументу. Після закінчення виклику результати обробки параметрівзмінних залишаються в аргументах, чого не можна сказати про параметризначення.

Змінні локальної пам'яті підпрограми не зіставлені ніяким іменам підпрограми, у якій записано виклик. А це значить, що після закінчення виконання виклику Локальна пам'ять стає недоступною в підпрограмі, що викликає, і можна вважати, що вона Звільняється. А раз так, то її можна наново зайняти під локальні змінні при виконанні наступного виклику якоїнебудь підпрограми.

І останнє зауваження про те, як при написанні підпрограми вибирати вид параметра – параметрзначення чи параметрзмінна.

Якщо після виклику підпрограми повинно використовуватися нове значення аргументу, одержане при виконанні виклику, то відповідний параметр слід означити як параметрзмінну. Наприклад, як параметри в остаточному варіанті процедури swap із підрозділу 3.4.

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

З останнього правила, утім, є винятки, пов'язані з параметрами та аргументами, що є масивами. Про це йтиметься в підрозділі 12.1.

Приклад 1. Розглянемо імітацію виконання програми з викликами підпрограм. Як і в підрозділі 7.1, будемо позначати локальну змінну, наприклад, L підпрограми F, як F. L, відрізняючи її від однойменної змінної програми. Вказівку точки повернення позначимо буквами ТП. Процес виконання програми

Program nested input, output;

Var a, b: integer;

Function f x: integer: integer;

Begin

X:= x + 1; f:= x

End;

Function g Var x: integer: integer;

Begin X:= x Div 2; g:= x End;

Begin A:= 12; b:= f g a End.

Відобразимо такою таблицею:

Що виконується

Стан пам'яті

A b

A:= 12

12 ?

Починається b:= fg12

12 ?

Виклик fg12

12 ?

F. x f. f ТП

12 ?

? ? b:=

Починається f. x:= g12

12 ?

? ? b:=

Виклик g12

G. x?

? ? b:=

G. g ТП

G. x:= 12

12 ?

? ? b:=

? f. x:=

G. x:= g. X div 2

6 ?

? ? b:=

? f. x:=

G. g:= g. X

6 ?

? ? b:=

6 f. x:=

Повернення з g

6 ?

? ? b:=

6 f. x:=

Закінчення f. x:= g12

6 ?

6 ? b:=

F. x:= f. x + 1

6 ?

7 ? b:=

F. f:= f. X

6 ?

7 7 b:=

Повернення з f

6 ?

7 7 b:=

Закінчення b:= fg12

6 7

Як видно з таблиці, перед виконанням виклику fga у локальній пам'яті функції F запам'ятовується точка повернення – присвоювання b:=fga. Виконання виклику fga починається обчисленням значення аргументу, відповідного її параметру X – виразу ga. При цьому запам'ятовується точка повернення – присвоювання f. x:=ga – і починається виконання виклику функції G з аргументом A. Цей аргумент підставляється за посиланням, і зміна G. x є зміною A. З виклику функції G повертається значення 6 і присвоюється параметру F. x. Пам'ять функції G звільняється. Тільки тепер починається виконання операторів функції F. У результаті в програму повертається значення 7 і присвоюється змінній B. Пам'ять функції F звільняється.