Підпрограми, Детальна інформація

Підпрограми
Тип документу: Реферат
Сторінок: 7
Предмет: Комп`ютерні науки
Автор: Олексій
Розмір: 17.1
Скачувань: 790
повернення з f 6 ? 7 7 b:=

закінчення b := f(g(12)) 6 7



Як видно з таблиці, перед виконанням виклику f(g(a)) у локальній пам'яті функції f запам'ятовується точка повернення – присвоювання b:=f(g(a)). Виконання виклику f(g(a)) починається обчисленням значення аргументу, відповідного її параметру x – виразу g(a). При цьому запам'ятовується точка повернення – присвоювання f.x:=g(a) – і починається виконання виклику функції g з аргументом a. Цей аргумент підставляється за посиланням, і зміна g.x є зміною a. З виклику функції g повертається значення 6 і присвоюється параметру f.x. Пам'ять функції g звільняється. Тільки тепер починається виконання операторів функції f. У результаті в програму повертається значення 7 і присвоюється змінній b. Пам'ять функції f звільняється.\xF0E7

5. Автоматична пам'ять та програмний стек

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

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

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

-

:

\

|

\x245B\x5C00$\x0091\x6B00\x1F64

\x245B\x5C00$\x0091\x6B00\xE564

\x1622\x9668\xDC4A\x3500\x8108\x0836\x4381\x1B4A\x5C00\x8108\x085D\x6181\x1B4A\x6D00\x2248\x7304\x2248\x3B04ам'яті при виконанні викликів підпрограм відбувається за принципом "останнім зайнятий – першим звільнений". Подібно тому, як заштовхують патрони в магазин автомата й вистрілюють. Останній із них вистрілюється першим, а перший, що на самому дні магазина, – останнім. Можна вистрілити один патрон із магазина і додати згори новий. Цьому відповідає закінчення виклику підпрограми, записаного в тілі деякої підпрограми, і початок виконання наступного виклику з цього ж тіла.

Якщо складати аркуші паперу в стопку і брати їх тільки згори, то лист, що потрапив у стопку останнім, забирається першим. По-англійському така стопка називається stack (стек), а кладуться і забираються аркуші за принципом "Last In – First Out" (LIFO), тобто "першим у – останнім із". Тому автоматична пам'ять програми називається програмним стеком. Таблиця в прикладі 1 показує, як зростає й зменшується програмний стек при виконанні викликів підпрограм.

6. Зберігання локальних змінних між викликами підпрограми

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

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

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

Приклад 2. У багатьох задачах, від моделювання природних або соціальних процесів і до розкладання карт, потрібні послідовності чисел, що належать деякій множині, але більше ніяк не пов'язані одне з одним. Такі числа називаються випадковими.

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

У багатьох генераторах використовується множина цілих чисел від 0 до m-1, де m – достатньо велике число. Нове число визначається за попереднім застосуванням рекурентного співвідношення вигляду

Vi+1=( a*Vi + c ) mod m.

Цей дуже простій у реалізації метод породження наступного числа називається лінійним конгруентним. Ми не будемо тут досліджувати, при яких значеннях параметрів a, c і m і чому утворюється послідовність, схожа на випадкову. Про це написано дуже багато, і достатньо заглянути в книгу Д.Кнута [Кнут, т.2]. Для прикладу візьмемо m=1001, a=21, c=57.

Наша задача – написати функцію, що задає обчислення та повернення наступного елемента послідовності за умови, що відомий попередній. Дамо їй ім'я NextRand – скорочення від "Next Random", або "наступне випадкове".

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

Ту змінну, чиїми значеннями є послідовні псевдовипадкові числа, означимо в нашій функції як статичну. Те, що змінна статична, якимось чином треба указати в її означенні. Наприклад, у мові Сі та деяких діалектах мови Паскаль там записуються додаткові позначення, щось на зразок

static var V : integer.

У діалекті Турбо Паскаль локальну статичну змінну задає означення з ініціалізацією (п.2.3.6), записане в підпрограмі. Нагадаємо його дещо дивний вигляд:

The online video editor trusted by teams to make professional video in minutes