Область видимости переменных

Время жизни переменных

Время жизни переменной начинается в момент связывания ее с определенной областью памяти и заканчивается при разрыве этой связи.

В зависимости от времени жизни все переменные можно разделить на четыре категории:

Ø Статические переменные;

Ø Автоматические переменные;

Ø Явные динамические переменные;

Ø Неявные динамические переменные.

Статические переменные связываются с областью памяти во время трансляции программы и остаются связанными с этой областью памяти до конца выполнения программы.

Автоматическими называются переменные со статическим связыванием типов, которые связываются с областью памяти при обработке операторов объявления переменных во время выполнения программы. Память автоматическим переменным выделяется из стека.

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

 

Пример: оператор 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.

 

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