Використання стека в програмуванні
Стек застосовується досить часто, причому в самих різних ситуаціях. Об'єднує їх наступна мета: потрібно зберегти деяку роботу, яка ще не виконана до кінця, при необхідності перемикання на інше завдання. Стек використовується для тимчасового збереження стану не виконаного до кінця завдання. Після збереження стану комп'ютер перемикається на інше завдання. Після закінчення її виконання стан відкладеного завдання відновлюється із стека, і комп'ютер продовжує перервану роботу.
Припустимо, що комп'ютер виконує завдання A. В процесі її виконання виникає необхідність виконати завдання B. Стан завдання A запам'ятовується, і комп'ютер переходить до виконання завдання B. Але ж і при виконанні завдання B комп'ютер може перемкнутися на інше завдання C, і потрібно буде зберегти стан завдання B, перш ніж перейти до C. Пізніше, після закінчення C буде спершу відновлено стан завдання B, потім, після закінчення B, — стан завдання A. Таким чином, відновлення відбувається в порядку, зворотному збереженню, що відповідає дисципліні роботи стека.
Стек дозволяє організувати рекурсію, тобто звернення підпрограми до самої собі або безпосередньо, або через ланцюжок інших викликів.
Насправді навіть не доводиться спеціальним чином зберігати значення локальних змінних підпрограми в стеку. Річ у тому, що локальні змінні підпрограми (тобто її внутрішні, робочі змінні, які створюються на початку її виконання і знищуються в кінці) розміщуються в стеку, реалізований апаратний на базі звичайної оперативної пам'яті. На самому початку роботи підпрограма захоплює місце в стеку під свої локальні змінні, цю ділянку пам'яті в апаратному стеку називають зазвичай блок локальних змінних або по-англійськи frame ( "кадр "). У момент закінчення роботи підпрограма звільняє пам'ять, видаляючи із стека блок своїх локальних змінних.
Окрім локальних змінних, в апаратному стеку зберігаються адреси повернення при викликах підпрограм. Хай в деякій точці програми A викликається підпрограма B. Перед викликом підпрограми B адреса інструкції, наступної за інструкцією виклику B, зберігається в стеку. Це так звана адреса повернення в програму A. Після закінчення роботи підпрограма B витягує із стека адресу повернення в програму A і повертає управління за цією адресою. Таким чином, комп'ютер продовжує виконання програми A, починаючи з інструкції, наступної за інструкцією виклику. У більшості процесорів є спеціальні команди, що підтримують виклик підпрограми з попереднім приміщенням адреси повернення в стек і повернення з підпрограми за адресою, витягуваною із стека. Зазвичай команда виклику назывется call, команда повернення — return.
У стек поміщаються також параметри підпрограми або функції перед її викликом. Порядок їх приміщення в стек залежить від угод, прийнятих в мовах високого рівня.
Реалізація стека на базі масиву
Реалізація стека на базі масиву є класикою програмування. Іноді навіть само поняття стека не цілком коректно ототожнюється з цією реалізацією.
Б
азою
реалізації є масив розміру N,
таким чином, реалізується стек обмеженого
розміру, максимальна глибина якого не
може перевищувати N.
Індекси осередків масиву змінюються
від 0 до N
- 1.
Елементи стека зберігаються в масиві
таким чином: елемент на дні стека
розташовується на початку масиву, тобто
в осередку з індексом 0. Елемент,
розташований над самим нижнім елементом
стека, зберігається в осередку з індексом
1, і так далі. Вершина стека зберігається
десь в середині масиву. Індекс елементу
на вершині стека зберігається в
спеціальній змінній, яку зазвичай
називають покажчиком
стека
(по-англійськи Stack
Pointer
або просто SP).
Коли стек порожній, покажчик стека містить значення мінус одиниця. При додаванні елементу покажчик стека спочатку збільшується на одиницю, потім в осередок масиву з індексом, що міститься в покажчику стека, записується елемент, що додається. При витяганні елементу із стека спершу вміст осередку масиву з індексом, що міститься в покажчику стека, запам'ятовується в тимчасовій змінній як результат операції, потім покажчик стека зменшується на одиницю.
У приведеній реалізації стек росте у бік збільшення індексів осередків масиву. Часто використовується інший варіант реалізації стека на базі вектора, коли дно стека поміщається в останній осередок масиву, тобто в осередок з індексом N - 1. Елементи стека займають безперервний відрізок масиву, починаючи з осередку, індекс якого зберігається в покажчику стека, і закінчуючи останнім осередком масиву. У цьому варіанті стек росте у бік зменшення індексів. Якщо стек порожній, то покажчик стека містить значення N (яке на одиницю більше, ніж індекс останнього осередку масиву).
