Область видимости переменных
Время жизни переменных
Время жизни переменной начинается в момент связывания ее с определенной областью памяти и заканчивается при разрыве этой связи.
В зависимости от времени жизни все переменные можно разделить на четыре категории:
Ø Статические переменные;
Ø Автоматические переменные;
Ø Явные динамические переменные;
Ø Неявные динамические переменные.
Статические переменные связываются с областью памяти во время трансляции программы и остаются связанными с этой областью памяти до конца выполнения программы.
Автоматическими называются переменные со статическим связыванием типов, которые связываются с областью памяти при обработке операторов объявления переменных во время выполнения программы. Память автоматическим переменным выделяется из стека.
Явные динамические переменные – это переменные, которые связываются с соответствующей областью памяти во время выполнения программы при обработке оператора создания программных объектов.
Пример: оператор new в языке С
Явные динамические переменные связываются с типом статически.
В некоторых языках имеются операторы для удаления явных динамических переменных.
Пример: оператор delete в языке C
Уничтожение явных динамических переменных – либо с помощью специального оператора (delete в C++), либо во время сборки мусора – специальной процедуры освобождения недоступных областей памяти, выполняемой в случае, если весь пул доступной памяти исчерпан.
Началом времени жизни явных динамических переменных является время выполнения оператора создания такой переменной, а концом – время разрыва связи между динамической переменной и соответствующей областью памяти.
Проблемы, связанные с использованием указателей:
Ø Наличие висячих указателей;
Ø Потерянные динамические переменные (мусор).
Висячий указатель – это указатель, содержащий адрес динамической переменной, уже удаленной из памяти.
Потерянная динамическая переменная (мусор) – это размещенная в памяти динамическая переменная, недоступная из прикладной программы.
Неявные динамические переменные – это переменные, которые связываются с соответствующей областью памяти только при присвоении им значений.
Ассоциация – пара (идентификатор, объект данных) – процесс связывания ссылок на переменные, объявленные вне выполняющейся в данный момент подпрограммы (блока).
Типовой процесс связывания состоит из следующих этапов:
1. В начале выполнения главной программы имя каждой объявленной в ней переменной связывается с конкретным объектом данных (областью памяти для хранения значений переменной), а каждое имя подпрограммы, – с конкретным определением подпрограммы.
2. При выполнении главной программы с помощью операций обработки ссылок для каждого идентификатора определяется ассоциированный с ним объект.
3. При обработке вызова каждой подпрограммы создается новое множество ассоциаций: имена локальных переменных, объявленных в подпрограмме, и имена формальных параметров связываются с конкретными объектами данных.
4. При выполнении подпрограммы операции обработки ссылок определяют конкретные объекты, ассоциированные с каждым идентификатором. При этом ссылки могут быть как ссылками на ассоциации, созданные при входе в подпрограмму, так и на глобальные ассоциации.
5. При выходе из подпрограммы созданные в ней ассоциации уничтожаются.
6. Когда управление возвращается в главную программу, доступными становятся только глобальные ассоциации.
Эта модель позволяет программе (подпрограмме) иметь множество ассоциаций, доступных для разрешения ссылок во время их выполнения, а программисту – управлять памятью.
Среда ссылок (множество ассоциаций подпрограммы) обычно не изменяется при выполнении подпрограммы и включает в себя:
Ø Среду локальных ссылок (локальную среду), в которую входят все ассоциации, созданные при передаче управления данной подпрограмме. В нее включаются формальные параметры, локальные переменные и подпрограммы, определенные в данной программе;
Ø Среду нелокальных ссылок, содержащую ассоциации, которые могут использоваться в подпрограмме, но были созданы до момента входа в данную подпрограмму;
Ø Среду глобальных ссылок, созданную в начале выполнения главной программы и являющуюся частью среды нелокальных ссылок;
Ø Среду предопределенных ссылок, задаваемую непосредственно в определении языка, которую можно использовать в любой программе или подпрограмме.
Пример:
program main; var A, B, C: integer; procedure Sub1(A: integer); var C, D: integer; procedure Sub11(C: integer); var D: integer; begin {Sub11} <операторы Sub11> end; {Sub11} begin {Sub1} <операторы Sub1> end; {Sub1} procedure Sub2(B: integer); var A: integer; procedure Sub21(A: integer); var D: integer; begin {Sub21} <операторы Sub21> end; {Sub21} procedure Sub22(D: integer); var A, B, C: integer; begin{Sub22} <операторы Sub22> end; {Sub22} begin {Sub2} <операторы Sub2> end; {Sub2} begin <операторы main> end. | Среда ссылок для Sub1 Локальные: A, C, D, Sub11 Нелокальные: B, Sub1 из main Среда ссылок для Sub11 Локальные: C, D Нелокальные: A, Sub1 из Sub1, Bиз main Среда ссылок для Sub2 Локальные: A, B, Sub21, Sub22 Нелокальные: C, Sub2 из main Среда ссылок для Sub21 Локальные: A, D Нелокальные: B, Sub21 из Sub2, C из main Среда ссылок для Sub22 Локальные: A, B, C, D Нелокальные: Sub22 из Sub2 |
Проблема разрешения ссылок – связывание идентификатора и значения соответствующей величины. Проблема решается введением в язык понятия области видимости.
Ассоциация для идентификатора видима в подпрограмме, если она является частью ее среды ссылок. Ассоциация для идентификатора скрыта от подпрограммы, если она не входит в среду ссылок выполняющейся в данный момент времени подпрограммы.
Если при входе в подпрограмму некоторый идентификатор переопределяется, то ассоциация, в которую он входил до этого момента времени, становится скрытой.
Статическая область видимости имен – это область видимости, которая может быть определена во время трансляции программы.
Графическое представление структуры программы:
РИС.1.1. Поиск ассоциации для идентификатора B.
Правила статической области видимости позволяют определить множество различных типов связей между ссылками на имена и их объявлениями только один раз во время трансляции программы. К таким типам относятся:
Ø Связывание имени переменной с объявлением переменной;
Ø Связывание имени константы с объявлением константы;
Ø Связывание имени типа с объявлением типа;
Ø Связывание формального параметра со спецификацией формального параметра;
Ø Связывание вызова подпрограммы с объявлением подпрограммы;
Ø Связывание метки оператора, используемой в операторе перехода, с меткой конкретного оператора.
Недостатки:
Ø Можно по ошибке вызвать подпрограмму, вызов которой не должен допускаться.
Ø Слишком интенсивное обращение к данным.
Ø Тяжело модифицировать программу.
Ø При объявлении всех переменных в главной программе ухудшается удобочитаемость.
Динамическая область видимости имен (в языках APL и Snobol) представляет собой множество активаций подпрограмм, в которых ассоциации идентификаторов видимы во время выполнения программы. Динамическая область видимости имен опирается на последовательность вызовов подпрограмм.
Пример:
procedure example;
var A: integer;
procedure Sub1;
begin {Sub1}
<операторы Sub1>
end; {Sub1}
procedure Sub2;
var A: integer;
begin {Sub2}
<операторы Sub2>
end; {Sub2}
begin {example}
<операторы example>
end;
Возможные вызовы процедуры Sub1:
РИС.1.2. Возможные вызовы процедуры Sub1.
Использование динамической области видимости имен приводит к тому, что подпрограммы всегда выполняются в непосредственной среде вызывающей процедуры, поэтому они менее надежны. Обращение к нелокальным переменным в языках с динамической областью видимости имен занимает значительно больше времени, чем в языках со статической областью видимости.