область видимости, глобальные и локальные переменные

Предыдущая тема Следующая тема Перейти вниз

область видимости, глобальные и локальные переменные

Сообщение  Eric-S в Вт Авг 25, 2009 2:28 pm

Область видимости это больше понятие, чем некая конструкция.

Область видимости необходима для разделения идентификаторов. В первую очередь имён переменных.

Внутри каждой процедуры или функции создаёться своя область видимости.
Это позволяет создавать в разных функциях две или более одноимённых переменных.

Код:

' первая процедура
sub foot()
dim a as integer
a = 333
print "foot. a = "; a
end sub

' вторая процедура
sub bar()
dim a as string
a = "test"
print "foot. a = "; a
end sub

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

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

Глобальная переменная должна быть объявлена вне функций с ключевым словом shared.


Код:

' создаём глобальную переменную
dim shared b as integer

' первая процедура
sub foot()
dim a as integer
' выведем глобальную переменную
print "shared b = "; b
end sub

Таким образом переменная b[i/i] становиться видной в процедуре [i]foot.
Да и не только, но и в любой другой процедуре или функции.

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

Код:

' глобальная переменная
dim shared b as integer

' вторая процедура
sub bar()
' создаём локальную переменную
dim b as integer
b = 456

' выведем локальную переменную
print "local b = "; b
end sub

В процедуре bar[i]создаёться переменная [i]b. Она становиться главнее, но при этом глобальная переменная b просто становиться невидимой.



Примерно такая же вещь происходит в классах.
Код:

type SomeClass
declare sub foot()
value as integer
end type


sub SomeClass.foot()
' здесь к свойству value мы можем доступ получить напрямую
value = 333

' или пояснив, что речь идёт именно о свойстве
this.value = 666

' если же создадим одноимённую локальную переменную, то просто
value = 555
' будем обращаться именно к локальной
' а ксвойству только через
this.value = 111

end sub

Область видимости, как листок кальки.
берём простую бумажку и на ней рисуем.
кладём кальку, но рисунок по прежнему виден.
Мы можем нарисовать своё, по верх первого рисунка.
Но сняв кальку увидим, что первый рисунок всё такой же.

Точно так же работает блок scope ... end scope. Это как раз наложение и снятие кальки.

Код:

' создаём общую переменную
dim a as integer = 123
print "global: "; a

' начинаем вложенную область видимости
scope

' создаём локальную переменную,
' которая перекроет одноимённую, созданную на более высоком уровне
dim a as integer = 456
print "local: "; a

' закрываем вложенную область видимости
end scope

' теперь переменная из общей области опять доступна
print "global: "; a


Все контейнеры, так же проделывают это наложение области видимости.
sub / function
класс ((включая методы)
if ... ed if
select case ... end select
do ... loop
for ... next
scope .. end scope
Кстати ещё одно замечательное свойство области видимости. Оно почему-то не очевидно.

При создании объекта, вызываеться его конструктор.
И деструктор вызываеться при его разрушении.

Код:

dim a as integer = 15

scope
dim a as integer ' это не ошибка
dim b as integer = 8

' изменяем локальную переменную
a = 123
print a, b ' выведет 123 8

' область видимости закрываеться и объект разрушаеться
end scope

print a ' выведет 15, это переменная осталась по прежнему

print b ' не допустимо, переменной b не существует!

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

Код:

Таким образомfor i = 1 to 3
scope

' создаём переменную
dim a as integer

' используем переменную
a = i + 1
print a * i

' а теперь переменная будет разрушена
end scope
next

Обратите внимание, что переменная a в нашем цикле будет 3 раза создана и три раза разрушена. После цикла мы уже не сможем получить к ней доступа.

Вам не нужно в циклах или петлях указывать контейнер scope ... end scope, компилятор сделает это за вас.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: область видимости, глобальные и локальные переменные

Сообщение  electrik в Ср Авг 26, 2009 2:42 pm

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

Код:

dim a as integer = 87125
scope
dim b as integer = 1234
print b
end scope
print a
dim c as integer = 54937
scope
dim d as integer = 723584
print d
end scope
print c

код сгенерированный на ассемблере:

Код:

mov dword ptr [ebp-8], 87125 ; dim a as integer = 87125
; здесь начинается блок scope
mov dword ptr [ebp-16], 1234 ; dim b as integer = 1234
push 1
push dword ptr [ebp-16] ; заносим в стек переменную b
push 0
call _fb_PrintInt@12 ; print b
; здесь заканчивается блок scope и компилятор забыл что у него когда-то была переменная b
push 1
push dword ptr [ebp-8] ; заносим в стек переменную a
push 0
call _fb_PrintInt@12 ; print a
mov dword ptr [ebp-12], 54937 ; dim c as integer = 54937
; здесь начинается блок scope
mov dword ptr [ebp-16], 723584 ; dim d as integer = 723584
; все наверное поняли, что по адресу dword ptr [ebp-16], в предыдущем блоке, лежала переменная b
; поскольку, блок scope закончился, значит эта ячейка памяти свободна для новой переменной
push 1
push dword ptr [ebp-16] ' заносим в стек переменную d
push 0
call _fb_PrintInt@12 ; print d
; здесь заканчивается блок scope
push 1
push dword ptr [ebp-12] ' занесем в стек переменную c
push 0
call _fb_PrintInt@12 ; print c

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 37
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: область видимости, глобальные и локальные переменные

Сообщение  Eric-S в Ср Авг 26, 2009 3:21 pm

Когда в контейнере scope ... end scope оказываеться объект класса, то становиться ещё интереснее.
Я скоро об этом расскажу в другой главе "dвремя жизни объекта".

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: область видимости, глобальные и локальные переменные

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения