Стек вызовов
Стек вызовов — это область памяти, в которой программа хранит сведения о подпрограммах, выполняющихся в данный момент. Он помогает запомнить, куда вернуться после завершения вызова, и сохранить локальные переменные каждой подпрограммы.
При [[function-definition:определении функции]] описывается, какие параметры и локальные переменные у неё есть, а при [[function-call:вызове функции]] для них создаётся новый кадр. Область действия локальных имён определяется [[subprogram-scope:областью видимости]]. Поэтому одинаковые имена локальных переменных в разных кадрах не смешиваются.
Как работает стек
- Программа вызывает подпрограмму и помещает её кадр на вершину стека.
- Подпрограмма выполняется, используя параметры и локальные данные своего кадра.
- После возврата кадр удаляется, и управление передаётся обратно в место вызова.
Пусть основная программа вызывает функцию \(A\), а \(A\) вызывает функцию \(B\). Сначала стек содержит кадр основной программы. После вызова \(A\) сверху появляется кадр \(A\), затем после вызова \(B\) — кадр \(B\). Первой завершится \(B\): её кадр удалится, затем управление вернётся в \(A\). После завершения \(A\) удалится и её кадр.
Стек вызовов — не то же самое, что [[call-graph:граф вызовов]]. Граф показывает возможные связи между подпрограммами, а стек — текущую последовательность реально активных вызовов. При глубокой или бесконечной рекурсии стек может переполниться.
В каком порядке удаляются кадры при вызовах \(A\), затем \(B\)?
Главное
- Стек вызовов хранит активные вызовы подпрограмм и их локальные данные.
- Каждый вызов создаёт кадр, а после возврата этот кадр удаляется.
- Кадры обрабатываются по принципу LIFO; это особенно важно при рекурсии.