Введение в области видимости переменных
 
Автор rdc

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


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

Структура программы

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

Dim aInt As Integer 'Переменная, объявленная на уровне модуля

Sub DoSomething
    Dim aInt As Integer 'Переменная, объявленная на уровне процедуры
    
    ... 'Этот код является локальным для процедуры
End Sub

Function DoSomethingElse() As Integer
    Dim aInt As Integer 'Переменная, объявленная на уровне функции
    
    ... 'Этот код является локальным для функции
End Function

'код на уровне модуля
aInt = 5
DoSomething
aInt = DoSomethingElse()


Локальные переменные

Если вы определяете переменную на уровне модуля (не с помощью Shared), переменная как говорят локальная для текущей области видимости модуля. Она видна в коде на уровне модуля, но не видна в любой подпрограмме или функции в пределах модуля. В примере выше переменная aInt является видимой только для кода уровня модуля

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

Переменные, определенные в рамках управляемых структур

Переменные, определенные в конструкциях If, For-Next, While-Wend и Do-Loop являются локальными для блока кода этой управляемой структуры. То есть переменные не видны за пределами границ начала и конца этого блока управления, так же, как переменная, объявленная внутри подпрограммы или функции.

Shared переменные

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

Конфликт областей видимости

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

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

Несколько модулей

Область видимости ограничена одним модулем, который представляет собой единый .bas файл. Однако иногда бывает необходимо расширить видимость для других модулей. Вы можете использовать спецификатор Common при объявлении переменной, которая должна быть видима между модулями.

Каждый модуль должен иметь такую же декларацию с Common для того, чтобы компилятор  сопоставил Common переменные. Если объявить переменную в module1 как Common aInt as Integer , то и в module2 необходимо также продекларировать Common aInt as Integer. Без Common декларации aInt не будет видна в module2.

Можно добавить атрибут Shared для Common, то есть Common Shared , что сделает переменную видной не только для нескольких модулей, но видной для всех частей каждого модуля, в котором они объявлены. Common Shared функционирует так же, как Shared в одном модуле.

Scope...End Scope


Временные рамки блока видимости можно создать с помощью ключевых слов Scope, End Scope. Блок Scope очень полезен при создании многострочных макросов , в которых может потребоваться создать некоторые временные рабочие переменные, чтобы не создавать конфликты имен в программе. В следующем фрагменте показано, как создать блок Scope.

Scope
    Dim tmp As Integer
    ... 'Некоторый код
End Scope


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

Например если у вас есть переменная aInt, которая определена на уровне модуля, и блок Scope находится на этом же уровне модуля, то переменная aInt будет видна внутри блока Scope. Если образуется конфликт областей (в Scope объявлена переменная с тем же именем), то в этом случае переменная внутри Scope будет использоваться, а переменная объявленная вне этого блока не будет.

Время существования переменной


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

Переменные на уровне модуля

Переменные уровня модуля существуют в течение всего срока программы, так как они объявлены в области основной части программы. Код уровня модуля является основным выполнением кода программы, и заканчивается, когда заканчивается программа.

Переменные на уровне процедур и функций

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

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

Единственным исключением из объявлямых переменных внутри процедур/функций является статическая переменная Static. Статические переменные или Static сохраняют свое значение между вызовами подпрограмм или функций и поэтому имеют продолжительность жизни уровня модуля.

Переменные на уровне управляемых блоков

Переменные, объявленные в управляемых блоках, таких как FOR-NEXT, существуют, пока управляемый блок выполняется. После выхода из управляемого блока, переменные уничтожаются.

Scope...End Scope переменные

Переменные, объявленные в блоке Scope существуют, пока выполняется код блока Scope. После того как программа покидает блок Scope, любые переменные, созданные в этом блоке разрушаются.