Читаем Освой самостоятельно С++ за 21 день. полностью

Аналогия со стопкой тарелок приводится чаще всего. Такое сравнение довольно наглядно, но не вполне верно в смысле техники выполнения. Более точное представление позволит создать ряд прямоугольных полей, выровненных сверху вниз. Вершиной стека будет служить любое поле, на которое указывает в данный момент указатель вершины стека (эту роль выполняет другой регистр).

Все поля имеют последовательные адреса, и один из этих адресов хранится в регистре указателя вершины стека. Все, что находится ниже вершины стека, относится к стеку. Все, что находится выше вершины стека, игнорируется, как показано на рис. 5.8.

Рис. 5.8. Указатель вершины стека

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

Рис. 5.9. Перемещение указателя вершины стека

Стек и функции

Ниже перечислены действия, происходящие с программой, выполняемой под управлением DOS, при переходе к телу функции.

1. Увеличивается адрес, содержащийся в указателе команды, чтобы указывать на инструкцию, следующую после вызова функции. Затем этот адрес помещается в стек и будет служить адресом возврата по завершении выполнения функции.

2. В стеке резервируется место для возвращаемого функцией значения объявленного вами типа. Если в системе с двухбайтовыми целыми для возвращаемого значения объявлен тип int, то к стеку добавляются еще два байта, но в эти байты ничего пока не помещается.

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

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

5. В стек помещаются все аргументы, передаваемые функции.

6. Выполняется команда, адрес которой находится в данный момент в указателе команды, т.е. первая строка кода функции.

7. По мере определения в стеке размещаются локальные переменные и функции.

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

Затем из стека извлекаются значение возврата функции, которое присваивается переменной, вызвавшей функцию, и адрес команды, сохраненный в стеке на этапе 1, который присваивается указателю команд. Таким образом, программа продолжает свою работу со следующей строки после обращения к функции, владея уже значением, возвращенным из функции.

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

На следующих занятиях рассматриваются некоторые особенности других областей памяти, которые используются для хранения глобальных данных программы.

Резюме

На этом занятии вы познакомились с функциями. Функция в действительности представляет собой подпрограмму, которой можно передавать параметры и из которой можно возвращать значение. Каждый запуск программы C++ начинается с выполнения функции main, которая, в свою очередь, может вызывать другие функции.

Функция объявляется с помощью прототипа функции, который описывает возвращаемое значение, имя функции и типы ее параметров. При желании функцию можно объявить подставляемой (с помощью ключевого слова inline). В прототипе функции можно также объявить значения, используемые по умолчанию для одного или нескольких параметров функции.

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

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

Вопросы и ответы

Почему бы не сделать все переменные глобальными?

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT