Lt304888.ru

Туристические услуги

FILO

30-06-2023

Иллюстрация организации стека

Стек (англ. stack — стопка) — структура данных, представляющая из себя список элементов организованных по принципу LIFO (англ. last in — first out, «последним пришёл — первым вышел»).

Чаще всего принцип работы стека сравнивают со стопкой тарелок: чтобы взять вторую сверху, нужно снять верхнюю.

В цифровом вычислительном комплексе стек называется магазином — по аналогии с магазином в огнестрельном оружии (стрельба начнётся с патрона, заряженного последним)

В 1946 М. Тьюринг ввел понятие стека[1]. А в 1957 году немцы Клаус Самельсон и Фридрих Л. Бауэр запатентовали идею[2].

В некоторых языках(например, Lisp, Python[3]) стеком можно назвать любой список, так как для них доступны операции pop и push. В языке C++ стандартная библиотека имеет класс с реализованной структурой и методами[4]. И т. д.

Содержание

Программный стек

Организация в памяти

Зачастую стек реализуется в виде однонаправленного списка(каждый элемент списка указывает только на следующий). Но в таком случае невозможно применить операцию обхода элементов. А доступ возможен только к верхнему элементу структуры. Для обхода такой проблемы можно взять за основу двусвязный список(каждый элемент указывает на обоих соседей справа и слева). Кроме того можно организовать его на обыкновенном массиве.

Значением переменной стека является указатель на вершину стека. Если стек пуст, то значение указателя равно NULL.

Пример реализации стека на языке Си:

struct stack
{
    char *data;
    struct stack *next;
};

Операции со стеком

Возможны три операции со стеком: добавление элемента(иначе проталкивание, push), удаление элемента(pop) и чтение головного элемента(peek)[5].

При проталкивании(push) указывается новый элемент, указывающий на элемент бывший до этого головой. Новый элемент теперь становится головным.

При удалении элемента убирается первый, а головным становится тот, на который был указатель у этого объекта(следующий элемент).

void push( STACK *ps, int x ) // Добавление в стек нового элемента
{
    if ( ps->size == STACKSIZE ) // Не переполнен ли стек?
    {
        fputs( "Error: stack overflow\n", stderr );
        abort();
    }
    else
    {
        ps->items[ps->size++] = x;
    }
}
 
int pop( STACK *ps ) // Удаление из стека
{
    if ( ps->size == 0 ) // Не опустел ли стек?
    {
        fputs( "Error: stack underflow\n", stderr );
        abort();
    }
    else
    {
        return ps->items[--ps->size];
    }
}

Аппаратный стек (Hardware stack)

Аппаратный стек — непрерывная область памяти, адресуемая специальными регистрами ESP (указатель стека) и SS (селектор сегмента стека)[6].

До использования стека он должен быть инициализирован так, чтобы регистры SS:ESP указывали на область реальной оперативной памяти (стек в ПЗУ, естественно, работать не может). Прикладные программы, как правило, от операционной системы получают готовый к употреблению стек. В защищенном режиме сегмент состояния задачи содержит четыре селектора сегментов стека (для разных уровней привилегий), но в каждый момент используется, естественно, только один стек[7].

Область применения

Аппаратный стек

Стек применяется в случаях, когда необходимо организовать прерывания вызовов и возвратов(см. локальная область видимости у функций в си-подобных языках), либо в случаях, когда нужно организовать временное хранилище данных места в памяти(переменные, параметры функции)[6].

Программный стек

Программный вид стека используется для обхода структур данных, например, дерево или граф. При использовании рекурсивных функций так же будет применяться стек, но аппаратный его вид. Кроме этих назначений стек используется для организации стековой машины.

Для отслеживания точек возврата из подпрограмм используется стек вызовов.

Арифметические сопроцессоры, программируемые микрокалькуляторы и язык Forth используют стековую модель вычислений[8].

Идея стека используется в стековой машине среди стековых языков программирования.

Примечания

  1. Архивировано из первоисточника 15 февраля 2013. Проверено 12 февраля 2013.
  2. Немецкий патент. Архивировано из первоисточника 15 февраля 2013. Проверено 12 февраля 2013.
  3. Python списки: Встроенные функции. Архивировано из первоисточника 15 февраля 2013. Проверено 12 февраля 2013.
  4. LIFO stack. Архивировано из первоисточника 15 февраля 2013. Проверено 12 февраля 2013.
  5. Введение. Архивировано из первоисточника 15 февраля 2013. Проверено 11 февраля 2013.
  6. ↑ 8.1. Логическаяструктура памяти программы. Архивировано из первоисточника 26 февраля 2013. Проверено 20 февраля 2013.
  7. Стек. Архивировано из первоисточника 15 февраля 2013. Проверено 12 февраля 2013.
  8. Стек. Архивировано из первоисточника 15 февраля 2013. Проверено 12 февраля 2013.

FILO.

© 2020–2023 lt304888.ru, Россия, Волжский, ул. Больничная 49, +7 (8443) 85-29-01