Область видимости

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

В программировании, область видимости (англ. scope) обозначает область программы, в пределах которой идентификатор (имя) некоторой переменной продолжает быть связанным с этой переменной и возвращать её значение. За пределами области видимости тот же самый идентификатор может быть связан с другой переменной, либо быть свободным (не связанным ни с какой из них).

В большинстве языков программирования область видимости переменной определяется местом её объявления. Кроме того, область видимости может задаваться явно с помощью классов памяти или пространств имён.

Область видимости также может иметь смысл для языков разметки: например, в HTML областью видимости имени элемента управления является форма (HTML) от <form> до </form>[1].

Виды переменных по области видимости[править | править вики-текст]

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

В объектно-ориентированном программировании каждый объект содержит три специфические области видимости:

  • Закрытая (англ. private) — переменную можно использовать только в реализации объекта;
  • Общедоступная (англ. public) — переменную можно использовать при использовании и инициализации объекта;
  • Защищённая (англ. protected) — переменную можно использовать только в реализации объекта или его потомка[3].

Лексические vs. динамические области видимости[править | править вики-текст]

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

  • лексические области видимости, или лексический контекст (англ. lexical scope) — если областью видимости переменной является некоторая функция, то это означает, что область видимости ограничена текстом определения этой функции (имя переменной имеет значение внутри текста функции и считается неопределённым за его пределами).
  • динамические области видимости (англ. dynamic scope) — область видимости ограничена не текстом, а временем исполнения функции (переменная существует, пока функция выполняется, и исчезает, когда функция возвращает управление вызвавшему её коду).

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

Например, рассмотрим следующую программу:

x=1
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f # выведет 1 или 3?
echo $x # выведет 1 или 2?

Если язык, на котором написана эта программа, использует лексические области видимости, то g выводит и изменяет глобальную переменную x (поскольку определение g находится вне f) — так что программа выведет 1, затем 2. Если же данный язык использует динамические области видимости, то g выводит и изменяет локальную переменную x функции f (поскольку g вызывается изнутри f) — так что программа выведет 3, затем 1. В данном случае программа написана на bash, который использует динамический подход (поэтому она выводит 3, затем 1).

Примеры[править | править вики-текст]

Си[править | править вики-текст]

// Начинается глобальная область видимости.
int countOfUser = 0;

int main()
{
    // С этого момента объявляется новая область видимости, в которой видна глобальная.
    int userNumber[10];
}
#include <stdio.h>
int a = 0;  // глобальная переменная

int main()
{
    printf("%d", a); // будет выведено число 0
    {
       int a = 1; // объявлена локальная переменная а, глобальная переменная a не видна
       printf("%d", a); // будет выведено число 1
       {
          int a = 2; // еще локальная переменная в блоке, глобальная переменная a не видна, не видна и предыдущая локальная переменная
          printf("%d", a);  // будет выведено число 2
       }
    }
}

Примечания[править | править вики-текст]