Википедия

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

Область видимости (англ. scope) в программировании — часть программы, в пределах которой идентификатор, объявленный как имя некоторой программной сущности (обычно — переменной, типа данных или функции), остаётся связанным с этой сущностью, то есть позволяет посредством себя обратиться к ней. Говорят, что идентификатор объекта «виден» в определённом месте программы, если в данном месте по нему можно обратиться к данному объекту. За пределами области видимости тот же самый идентификатор может быть связан с другой переменной или функцией, либо быть свободным (не связанным ни с какой из них). Область видимости может, но не обязана совпадать с областью существования объекта, с которым связано имя.

Связывание идентификатора (англ. binding) в терминологии некоторых языков программирования — процесс определения программного объекта, доступ к которому даёт идентификатор в конкретном месте программы и в конкретный момент её выполнения. Это понятие по сути синонимично области видимости, но может быть более удобно при рассмотрении некоторых аспектов выполнения программ.

Области видимости входят друг в друга и составляют иерархию, от локальной области видимости, ограниченную функцией (или даже её частью), до глобальной, идентификаторы которой доступны во всей программе. Также в зависимости от правил конкретного языка программирования области видимости могут быть реализованы двумя способами: лексически (статически) или динамически.

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

Типы области видимости

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

  • Глобальная область видимости — идентификатор доступен во всём тексте программы (во многих языках действует ограничение — только в тексте, находящемся после объявления этого идентификатора).
  • Локальная область видимости — идентификатор доступен только внутри определённой функции (процедуры).
  • Видимость в пределах модуля может существовать в модульных программах, состоящих из нескольких отдельных фрагментов кода, обычно находящихся в разных файлах. Идентификатор, чьей областью видимости является модуль, доступен из любого кода в пределах данного модуля.
  • Пакет или пространство имён. В глобальной области видимости искусственно выделяется поименованная подобласть. Имя «привязывается» к этой части программы и существует только внутри неё. Вне данной области имя либо вообще недоступно, либо доступно ограниченно.

В ООП-языках дополнительно к вышеперечисленным могут поддерживаться специальные ограничения области видимости, действующие только для членов классов (идентификаторов, объявленных внутри класса или относящихся к нему):

  • Приватная (личная, закрытая) (англ. private) область видимости означает, что имя доступно только внутри методов своего класса.
  • Защищённая (англ. protected) область видимости означает, что имя доступно только внутри своего класса и его классов-потомков.
  • Общая (англ. public) область видимости означает, что имя доступно в пределах области видимости, к которой относится его класс.

Способы задания области видимости

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

  • Идентификатор, объявленный вне любого определения функции, процедуры, типа, является глобальным.
  • Идентификатор, объявленный внутри определения функции, является локальным в данной функции, то есть его областью видимости является эта функция.
  • Идентификатор, являющийся частью определения типа данных, в отсутствие дополнительных уточнений имеет ту же область видимости, что и идентификатор типа, в определение которого он входит.
  • В языках, поддерживающих модули, пакеты или пространства имён идентификатор, объявленный вне всех процедур и классов, по умолчанию относится к модулю, пакету или пространству имён, внутри которого находится его объявление. Сами пределы области видимости для пакета или пространства имён указываются с помощью специальных описаний, а модульная область видимости ограничивается обычно текущим файлом исходного текста программы. Особенностью этого типа видимости является то, что язык, как правило, содержит средства, позволяющие сделать идентификатор доступным и вне своего модуля (пакета или пространства имён), то есть «расширить» его область видимости. Для этого должно иметься сочетание двух факторов: содержащий идентификатор модуль должен быть импортирован с помощью специальной команды там, где предполагается его использование, а сам идентификатор при его описании должен быть дополнительно объявлен экспортируемым. Способы объявления идентификатора экспортируемым могут быть различны. Это могут быть специальные команды или модификаторы в описаниях, соглашения об именовании (например, в языке Go экспортируемыми являются идентификаторы пакетной области видимости, начинающиеся на заглавную букву). В ряде языков каждый модуль (пакет) искусственно делится на две части: раздел определений и раздел реализации, которые могут находиться как в пределах одного файла исходного кода (например, в Delphi), так и в разных (например, в языке Модула-2); экспортируемыми являются идентификаторы, объявленные в модуле определений.
  • Область видимости идентификатора, объявленного внутри ООП-класса, по умолчанию является либо приватной, либо общей. Иная область видимости придаётся с помощью специального описания (например, в C++ это модификаторы private, public, protected).

Приведённый перечень не исчерпывает всех нюансов определения области видимости, которые могут иметься в конкретном языке программирования. Так, например, возможны различные толкования сочетаний модульной области видимости и объявленной видимости членов ООП-класса. В одних языках (например, C++) объявление личной или защищённой области видимости для члена класса ограничивает доступ к нему из любого кода, не относящегося к методам своего класса. В других (Object Pascal) все члены класса, в том числе личные и защищённые, полностью доступны в пределах того модуля, в котором объявлен класс, а ограничения области видимости действуют только в других модулях, импортирующих данный.

Иерархия и разрешение неоднозначностей

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

Пакеты и пространства имён могут иметь несколько уровней вложенности, соответственно, вложенными будут и их области видимости. Отношения областей видимости модулей и классов могут сильно отличаться в разных языках. Локальные пространства имён также могут быть вложенными, причём даже в тех случаях, когда язык не поддерживает вложенные функции и процедуры. Так, например, в языке C++ вложенных функций нет, но каждый составной оператор (содержащий набор команд, заключённый в фигурные скобки) образует собственную локальную область видимости, в которой возможно объявление своих переменных.

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

program Example1; var   a,b,c: Integer; (* Глобальные переменные. *)  procedure f1;  var b,c: Integer (* Локальные переменные процедуры f1. *)  begin  a := 10; (* Изменяет глобальную a. *)  b := 20; (* Изменяет локальную b. *)  c := 30; (* Изменяет локальную с. *)  writeln(' 4: ', a, ',', b, ',', c);  end;  procedure f2;  var b,c: Integer (* Локальные переменные процедуры f2. *)  procedure f21;  var c: Integer (* Локальная переменная процедуры f21. *)  begin  a := 1000; (* Изменяет глобальную a. *)  b := 2000; (* Изменяет локальную b процедуры f2. *)  c := 3000; (* Изменяет локальную c процедуры f21.*)  writeln(' 5: ', a, ',', b, ',', c);  end;  begin  a := 100; (* Изменяет глобальную a. *)  b := 200; (* Изменяет локальную b. *)  c := 300; (* Изменяет локальную c. *)  writeln(' 6: ', a, ',', b, ',', c);  f21;  writeln(' 7: ', a, ',', b, ',', c);  end; begin  (* Инициализация глобальных переменных. *)  a := 1;   b := 2;  c := 3;  writeln(' 1: ', a, ',', b, ',', c);  f1;  writeln(' 2: ', a, ',', b, ',', c);  f2;  writeln(' 3: ', a, ',', b, ',', c); end. 

Так, при запуске приведённой выше программы на языке Паскаль будет получен следующий вывод:

 1: 1,2,3 4: 10,20,30 2: 10,2,3 6: 100,200,300 5: 1000,2000,3000 7: 1000,2000,300 3: 1000,2,3 

В функции f1 переменные b и c находятся в локальной области видимости, поэтому их изменения не затрагивают одноимённые глобальные переменные. Функция f21 содержит в своей локальной области видимости только переменную c, поэтому она изменяет и глобальную a, и b, локальную в объемлющей функции f2.

Лексические vs. динамические области видимости

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

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

Для «чистых» функций, которые оперируют только своими параметрами и локальными переменными, лексическая и динамическая области видимости всегда совпадают. Проблемы возникают, когда функция использует внешние имена, например, глобальные переменные или локальные переменные функций, в которые она входит или из которых вызывается. Так, если функция f вызывает не вложенную в неё функцию g, то при лексическом подходе функция 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() ни параметром, ни локальной переменной, то есть она должна быть связана со значением из области видимости, в которую входит g(). Если язык, на котором написана программа, использует лексические области видимости, то имя «x» внутри g() должно быть связано с глобальной переменной x. Функция g(), вызванная из f(), выведет первоначальное значение глобальной х, после чего поменяет его, и изменённое значение будет выведено последней строкой программы. То есть программа выведет сначала 1, затем 2. Изменения локальной x в тексте функции f() на этом выводе никак не отразятся, так как эта переменная не видна ни в глобальной области, ни в функции g().

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

И лексическое, и динамическое связывание имеют свои положительные и отрицательные стороны. Практически выбор между тем и другим разработчик делает исходя как из собственных предпочтений, так и из характера проектируемого языка программирования. Большинство типичных императивных языков высокого уровня, изначально рассчитанных на использование компилятора (в код целевой платформы или в байт-код виртуальной машины, не принципиально), реализуют статическую (лексическую) область видимости, так как она удобнее реализуется в компиляторе. Компилятор работает с лексическим контекстом, который статичен и не меняется при исполнении программы, и, обрабатывая обращение к имени, он может легко определить адрес в памяти, где располагается связанный с именем объект. Динамический контекст недоступен компилятору (так как он может меняться в ходе исполнения программы, ведь одна и та же функция может вызываться во множестве мест, причём не всегда явно), так что для обеспечения динамической области видимости компилятор должен добавить в код динамическую поддержку определения объекта, на который ссылается идентификатор. Это возможно, но снижает скорость работы программы, требует дополнительной памяти и усложняет компилятор.

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

Особенности связывания имён

В рамках как динамического, так и лексического подхода к связыванию имён могут быть нюансы, связанные с особенностями конкретного языка программирования или даже его реализации. В качестве примера рассмотрим два Си-подобных языка программирования: JavaScript и Go. Языки синтаксически довольно близки и оба используют лексическую область видимости, но, тем не менее, различаются деталями её реализации.

Начало области видимости локального имени

В следующем примере показаны два текстуально аналогичных фрагмента кода на JavaScript и Go. В обоих случаях в глобальной области видимости объявляется переменная scope, инициализированная строкой «global», а в функции f() сначала выполняется вывод значения scope, затем — локальное объявление переменной с тем же именем, инициализированное строкой «local», и, наконец, повторный вывод значения scope. Далее приведён реальный результат выполнения функции f() в каждом случае.

JavaScript Go
var scope = "global";  function f() {  alert(scope); // ?  var scope = "local";  alert(scope);  } 
var scope = "global" func f() { fmt.Println(scope) // ? var scope = "local" fmt.Println(scope) } 
undefined
local
global
local

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

  • В JavaScript областью видимости локальной переменной является вся функция, в том числе та её часть, которая находится до объявления; при этом инициализация этой переменной выполняется только в момент обработки строки, где она находится. На момент первого вызова alert(scope) локальная переменная scope уже существует и доступна, но ещё не получила значения, то есть, по правилам языка, имеет специальное значение undefined. Именно поэтому в помеченной строке будет выведено «undefined».
  • В Go используется более традиционный для этого типа языков подход, согласно которому область видимости имени начинается со строки, где оно объявляется. Поэтому внутри функции f(), но до объявления локальной переменной scope эта переменная недоступна, и помеченная знаком вопроса команда выводит значение глобальной переменной scope, то есть «global».

Блочная видимость

Ещё один нюанс в семантике лексической области видимости — наличие или отсутствие так называемой «блочной видимости», то есть возможности объявить локальную переменную не только внутри функции, процедуры или модуля, но и внутри отдельного блока команд (в Си-подобных языках — заключённого в фигурные скобки {}). Далее приведён пример идентичного кода на двух языках, дающего разные результаты выполнения функции f().

JavaScript Go
function f () {  var x = 3;  alert(x); for (var i = 10; i < 30; i+=10) { var x = i;  alert(x); } alert(x); // ? } 
func f() { var x = 3 fmt.Println(x) for i := 10; i < 30; i += 10 { var x = i fmt.Println(x) } fmt.Println(x) // ? } 
3
10
20
20
3
10
20
3

Разница проявляется в том, какое значение будет выведено последним оператором в функции f(), помеченным знаком вопроса в комментарии.

  • В JavaScript нет блочной области видимости (в версиях, предшествующих ES6), а повторное объявление локальной переменной работает просто как обычное присваивание. Присваивание x значений i внутри цикла for изменяет единственную локальную переменную x, которая была объявлена в начале функции. Поэтому после завершения цикла переменная x сохраняет последнее значение, присвоенное ей в цикле. Это значение и выводится в результате.
  • В Go блок операторов образует локальную область видимости, и объявляемая внутри цикла переменная x — это новая переменная, областью видимости которой является только тело цикла; она перекрывает x, объявленную в начале функции. Эта «дважды локальная» переменная получает в каждом проходе цикла новое значение и выводится, но её изменения не затрагивают объявленную вне цикла переменную x. После завершения цикла объявленная в нём переменная х прекращает своё существование, а первая x становится снова видна. Её значение остаётся прежним, оно и выводится в результате.

Видимость и существование объектов

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

  • Для переменных, память под которые выделяется и освобождается динамически (в куче), возможно любое соотношение видимости и существования. Переменная может быть объявлена и затем инициализирована, тогда объект, соответствующий имени, фактически появится позже вхождения в область видимости. Но объект может быть создан заранее, сохранён и затем присвоен переменной, то есть появиться раньше. То же и с удалением: после вызова команды удаления для переменной, связанной с динамическим объектом, сама переменная остаётся видимой, но её значение не существует, а обращение к нему приведёт к непредсказуемым результатам. С другой стороны, если команда удаления не вызвана, то объект в динамической памяти может продолжать существовать и после того, как ссылающаяся на него переменная вышла из области видимости.
  • Для локальных переменных со статическим классом памяти (в языках Си и C++) значение появляется (логически) в момент запуска программы. При этом имя находится в области видимости только при исполнении содержащей его функции. Причём в промежутках между функциями значение сохраняется.
  • Автоматические (в терминологии Си) переменные, создаваемые при входе в функцию и уничтожаемые при выходе, существуют в период времени, когда их имя видно. То есть для них времена доступности и существования практически можно считать совпадающими.

Примеры

Си

// Начинается глобальная область видимости. 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  }  } } 

Примечания

  1. Спецификация языка HTML Архивная копия от 4 декабря 2012 на Wayback Machine, переводчик: А. Пирамидин, intuit.ru, ISBN 978-5-94774-648-8, 17. Лекция: Формы.
  2. Области видимости. Дата обращения: 11 марта 2013. Архивировано 26 ноября 2019 года.

Википедия, чтение, книга, библиотека, поиск, нажмите, истории, книги, статьи, wikipedia, учить, информация, история, скачать, скачать бесплатно, mp3, видео, mp4, 3gp, jpg, jpeg, gif, png, картинка, музыка, песня, фильм, игра, игры, мобильный, телефон, Android, iOS, apple, мобильный телефон, Samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Сеть, компьютер, Информация о Область видимости, Что такое Область видимости? Что означает Область видимости?

Oblast vidimosti angl scope v programmirovanii chast programmy v predelah kotoroj identifikator obyavlennyj kak imya nekotoroj programmnoj sushnosti obychno peremennoj tipa dannyh ili funkcii ostayotsya svyazannym s etoj sushnostyu to est pozvolyaet posredstvom sebya obratitsya k nej Govoryat chto identifikator obekta viden v opredelyonnom meste programmy esli v dannom meste po nemu mozhno obratitsya k dannomu obektu Za predelami oblasti vidimosti tot zhe samyj identifikator mozhet byt svyazan s drugoj peremennoj ili funkciej libo byt svobodnym ne svyazannym ni s kakoj iz nih Oblast vidimosti mozhet no ne obyazana sovpadat s oblastyu sushestvovaniya obekta s kotorym svyazano imya Svyazyvanie identifikatora angl binding v terminologii nekotoryh yazykov programmirovaniya process opredeleniya programmnogo obekta dostup k kotoromu dayot identifikator v konkretnom meste programmy i v konkretnyj moment eyo vypolneniya Eto ponyatie po suti sinonimichno oblasti vidimosti no mozhet byt bolee udobno pri rassmotrenii nekotoryh aspektov vypolneniya programm Oblasti vidimosti vhodyat drug v druga i sostavlyayut ierarhiyu ot lokalnoj oblasti vidimosti ogranichennuyu funkciej ili dazhe eyo chastyu do globalnoj identifikatory kotoroj dostupny vo vsej programme Takzhe v zavisimosti ot pravil konkretnogo yazyka programmirovaniya oblasti vidimosti mogut byt realizovany dvumya sposobami leksicheski staticheski ili dinamicheski Oblast vidimosti takzhe mozhet imet smysl dlya yazykov razmetki naprimer v HTML oblastyu vidimosti imeni elementa upravleniya yavlyaetsya forma HTML ot lt form gt do lt form gt Tipy oblasti vidimostiV monolitnoj odnomodulnoj programme bez vlozhennyh funkcij i bez ispolzovaniya OOP mozhet sushestvovat tolko dva tipa oblasti vidimosti globalnaya i lokalnaya Prochie tipy sushestvuyut tolko pri nalichii v yazyke opredelyonnyh sintaksicheskih mehanizmov Globalnaya oblast vidimosti identifikator dostupen vo vsyom tekste programmy vo mnogih yazykah dejstvuet ogranichenie tolko v tekste nahodyashemsya posle obyavleniya etogo identifikatora Lokalnaya oblast vidimosti identifikator dostupen tolko vnutri opredelyonnoj funkcii procedury Vidimost v predelah modulya mozhet sushestvovat v modulnyh programmah sostoyashih iz neskolkih otdelnyh fragmentov koda obychno nahodyashihsya v raznyh fajlah Identifikator chej oblastyu vidimosti yavlyaetsya modul dostupen iz lyubogo koda v predelah dannogo modulya Paket ili prostranstvo imyon V globalnoj oblasti vidimosti iskusstvenno vydelyaetsya poimenovannaya podoblast Imya privyazyvaetsya k etoj chasti programmy i sushestvuet tolko vnutri neyo Vne dannoj oblasti imya libo voobshe nedostupno libo dostupno ogranichenno V OOP yazykah dopolnitelno k vysheperechislennym mogut podderzhivatsya specialnye ogranicheniya oblasti vidimosti dejstvuyushie tolko dlya chlenov klassov identifikatorov obyavlennyh vnutri klassa ili otnosyashihsya k nemu Privatnaya lichnaya zakrytaya angl private oblast vidimosti oznachaet chto imya dostupno tolko vnutri metodov svoego klassa Zashishyonnaya angl protected oblast vidimosti oznachaet chto imya dostupno tolko vnutri svoego klassa i ego klassov potomkov Obshaya angl public oblast vidimosti oznachaet chto imya dostupno v predelah oblasti vidimosti k kotoroj otnositsya ego klass Sposoby zadaniya oblasti vidimostiV prostejshih sluchayah oblast vidimosti opredelyaetsya mestom obyavleniya identifikatora V sluchayah kogda mesto obyavleniya ne mozhet odnoznachno zadat oblast vidimosti primenyayutsya specialnye utochneniya Identifikator obyavlennyj vne lyubogo opredeleniya funkcii procedury tipa yavlyaetsya globalnym Identifikator obyavlennyj vnutri opredeleniya funkcii yavlyaetsya lokalnym v dannoj funkcii to est ego oblastyu vidimosti yavlyaetsya eta funkciya Identifikator yavlyayushijsya chastyu opredeleniya tipa dannyh v otsutstvie dopolnitelnyh utochnenij imeet tu zhe oblast vidimosti chto i identifikator tipa v opredelenie kotorogo on vhodit V yazykah podderzhivayushih moduli pakety ili prostranstva imyon identifikator obyavlennyj vne vseh procedur i klassov po umolchaniyu otnositsya k modulyu paketu ili prostranstvu imyon vnutri kotorogo nahoditsya ego obyavlenie Sami predely oblasti vidimosti dlya paketa ili prostranstva imyon ukazyvayutsya s pomoshyu specialnyh opisanij a modulnaya oblast vidimosti ogranichivaetsya obychno tekushim fajlom ishodnogo teksta programmy Osobennostyu etogo tipa vidimosti yavlyaetsya to chto yazyk kak pravilo soderzhit sredstva pozvolyayushie sdelat identifikator dostupnym i vne svoego modulya paketa ili prostranstva imyon to est rasshirit ego oblast vidimosti Dlya etogo dolzhno imetsya sochetanie dvuh faktorov soderzhashij identifikator modul dolzhen byt importirovan s pomoshyu specialnoj komandy tam gde predpolagaetsya ego ispolzovanie a sam identifikator pri ego opisanii dolzhen byt dopolnitelno obyavlen eksportiruemym Sposoby obyavleniya identifikatora eksportiruemym mogut byt razlichny Eto mogut byt specialnye komandy ili modifikatory v opisaniyah soglasheniya ob imenovanii naprimer v yazyke Go eksportiruemymi yavlyayutsya identifikatory paketnoj oblasti vidimosti nachinayushiesya na zaglavnuyu bukvu V ryade yazykov kazhdyj modul paket iskusstvenno delitsya na dve chasti razdel opredelenij i razdel realizacii kotorye mogut nahoditsya kak v predelah odnogo fajla ishodnogo koda naprimer v Delphi tak i v raznyh naprimer v yazyke Modula 2 eksportiruemymi yavlyayutsya identifikatory obyavlennye v module opredelenij Oblast vidimosti identifikatora obyavlennogo vnutri OOP klassa po umolchaniyu yavlyaetsya libo privatnoj libo obshej Inaya oblast vidimosti pridayotsya s pomoshyu specialnogo opisaniya naprimer v C eto modifikatory private public protected Privedyonnyj perechen ne ischerpyvaet vseh nyuansov opredeleniya oblasti vidimosti kotorye mogut imetsya v konkretnom yazyke programmirovaniya Tak naprimer vozmozhny razlichnye tolkovaniya sochetanij modulnoj oblasti vidimosti i obyavlennoj vidimosti chlenov OOP klassa V odnih yazykah naprimer C obyavlenie lichnoj ili zashishyonnoj oblasti vidimosti dlya chlena klassa ogranichivaet dostup k nemu iz lyubogo koda ne otnosyashegosya k metodam svoego klassa V drugih Object Pascal vse chleny klassa v tom chisle lichnye i zashishyonnye polnostyu dostupny v predelah togo modulya v kotorom obyavlen klass a ogranicheniya oblasti vidimosti dejstvuyut tolko v drugih modulyah importiruyushih dannyj Ierarhiya i razreshenie neodnoznachnostejOblasti vidimosti v programme estestvennym obrazom sostavlyayut mnogourovnevuyu strukturu v kotoroj odni oblasti vhodyat v sostav drugih Ierarhiya oblastej obychno stroitsya na vseh ili nekotoryh urovnyah iz nabora globalnaya paketnye modulnye klassov lokalnye konkretnyj poryadok mozhet neskolko otlichatsya v raznyh yazykah Pakety i prostranstva imyon mogut imet neskolko urovnej vlozhennosti sootvetstvenno vlozhennymi budut i ih oblasti vidimosti Otnosheniya oblastej vidimosti modulej i klassov mogut silno otlichatsya v raznyh yazykah Lokalnye prostranstva imyon takzhe mogut byt vlozhennymi prichyom dazhe v teh sluchayah kogda yazyk ne podderzhivaet vlozhennye funkcii i procedury Tak naprimer v yazyke C vlozhennyh funkcij net no kazhdyj sostavnoj operator soderzhashij nabor komand zaklyuchyonnyj v figurnye skobki obrazuet sobstvennuyu lokalnuyu oblast vidimosti v kotoroj vozmozhno obyavlenie svoih peremennyh Ierarhicheskaya struktura pozvolyaet razreshat neodnoznachnosti kotorye voznikayut kogda odin i tot zhe identifikator ispolzuetsya v programme bolee chem v odnom znachenii Poisk nuzhnogo obekta vsegda nachinaetsya s toj oblasti vidimosti v kotoroj raspolagaetsya obrashayushijsya k identifikatoru kod Esli v dannoj oblasti vidimosti nahoditsya obekt s nuzhnym identifikatorom to imenno on i ispolzuetsya Esli takovogo net translyator prodolzhaet poisk sredi identifikatorov vidimyh v obemlyushej oblasti vidimosti esli ego net i tam v sleduyushej po urovnyu ierarhii program Example1 var a b c Integer Globalnye peremennye procedure f1 var b c Integer Lokalnye peremennye procedury f1 begin a 10 Izmenyaet globalnuyu a b 20 Izmenyaet lokalnuyu b c 30 Izmenyaet lokalnuyu s writeln 4 a b c end procedure f2 var b c Integer Lokalnye peremennye procedury f2 procedure f21 var c Integer Lokalnaya peremennaya procedury f21 begin a 1000 Izmenyaet globalnuyu a b 2000 Izmenyaet lokalnuyu b procedury f2 c 3000 Izmenyaet lokalnuyu c procedury f21 writeln 5 a b c end begin a 100 Izmenyaet globalnuyu a b 200 Izmenyaet lokalnuyu b c 300 Izmenyaet lokalnuyu c writeln 6 a b c f21 writeln 7 a b c end begin Inicializaciya globalnyh peremennyh a 1 b 2 c 3 writeln 1 a b c f1 writeln 2 a b c f2 writeln 3 a b c end Tak pri zapuske privedyonnoj vyshe programmy na yazyke Paskal budet poluchen sleduyushij vyvod 1 1 2 3 4 10 20 30 2 10 2 3 6 100 200 300 5 1000 2000 3000 7 1000 2000 300 3 1000 2 3 V funkcii f1 peremennye b i c nahodyatsya v lokalnoj oblasti vidimosti poetomu ih izmeneniya ne zatragivayut odnoimyonnye globalnye peremennye Funkciya f21 soderzhit v svoej lokalnoj oblasti vidimosti tolko peremennuyu c poetomu ona izmenyaet i globalnuyu a i b lokalnuyu v obemlyushej funkcii f2 Leksicheskie vs dinamicheskie oblasti vidimostiIspolzovanie lokalnyh peremennyh imeyushih ogranichennuyu oblast vidimosti i sushestvuyushih lish vnutri tekushej funkcii pomogaet izbezhat konflikta imyon mezhdu dvumya peremennymi s odinakovymi imenami Odnako sushestvuet dva ochen raznyh podhoda k voprosu o tom chto znachit byt vnutri funkcii i sootvetstvenno dva varianta realizacii lokalnoj oblasti vidimosti leksicheskaya oblast vidimosti ili leksicheskij kontekst angl lexical scope ili leksicheskoe staticheskoe svyazyvanie angl lexical static binding lokalnaya oblast vidimosti funkcii ogranichena tekstom opredeleniya etoj funkcii imya peremennoj imeet znachenie vnutri tela funkcii i schitaetsya neopredelyonnym za ego predelami dinamicheskaya oblast vidimosti ili dinamicheskij kontekst angl dynamic scope ili dinamicheskoe svyazyvanie angl dynamic binding lokalnaya oblast vidimosti ogranichena vremenem ispolneniya funkcii imya dostupno poka funkciya vypolnyaetsya i ischezaet kogda funkciya vozvrashaet upravlenie vyzvavshemu eyo kodu Dlya chistyh funkcij kotorye operiruyut tolko svoimi parametrami i lokalnymi peremennymi leksicheskaya i dinamicheskaya oblasti vidimosti vsegda sovpadayut Problemy voznikayut kogda funkciya ispolzuet vneshnie imena naprimer globalnye peremennye ili lokalnye peremennye funkcij v kotorye ona vhodit ili iz kotoryh vyzyvaetsya Tak esli funkciya f vyzyvaet ne vlozhennuyu v neyo funkciyu g to pri leksicheskom podhode funkciya g ne imeet dostupa k lokalnym peremennym funkcii f Pri dinamicheskom zhe podhode funkciya g budet imet dostup k lokalnym peremennym funkcii f poskolku g byla vyzvana vo vremya raboty f Naprimer rassmotrim sleduyushuyu programmu x 1 function g echo x x 2 function f local x 3 g f vyvedet 1 ili 3 echo x vyvedet 1 ili 2 Funkciya g vyvodit i izmenyaet znachenie peremennoj x no eta peremennaya ne yavlyaetsya v g ni parametrom ni lokalnoj peremennoj to est ona dolzhna byt svyazana so znacheniem iz oblasti vidimosti v kotoruyu vhodit g Esli yazyk na kotorom napisana programma ispolzuet leksicheskie oblasti vidimosti to imya x vnutri g dolzhno byt svyazano s globalnoj peremennoj x Funkciya g vyzvannaya iz f vyvedet pervonachalnoe znachenie globalnoj h posle chego pomenyaet ego i izmenyonnoe znachenie budet vyvedeno poslednej strokoj programmy To est programma vyvedet snachala 1 zatem 2 Izmeneniya lokalnoj x v tekste funkcii f na etom vyvode nikak ne otrazyatsya tak kak eta peremennaya ne vidna ni v globalnoj oblasti ni v funkcii g Esli zhe yazyk ispolzuet dinamicheskie oblasti vidimosti to imya x vnutri g svyazyvaetsya s lokalnoj peremennoj x funkcii f poskolku g vyzyvaetsya iznutri f i vhodit v eyo oblast vidimosti Zdes funkciya g vyvedet lokalnuyu peremennuyu x funkcii f i izmenit eyo zhe a na znachenii globalnoj x vsyo eto nikak ne skazhetsya poetomu programma vyvedet snachala 3 zatem 1 Poskolku v dannom sluchae programma napisana na bash kotoryj ispolzuet dinamicheskij podhod v realnosti imenno tak i proizojdyot I leksicheskoe i dinamicheskoe svyazyvanie imeyut svoi polozhitelnye i otricatelnye storony Prakticheski vybor mezhdu tem i drugim razrabotchik delaet ishodya kak iz sobstvennyh predpochtenij tak i iz haraktera proektiruemogo yazyka programmirovaniya Bolshinstvo tipichnyh imperativnyh yazykov vysokogo urovnya iznachalno rasschitannyh na ispolzovanie kompilyatora v kod celevoj platformy ili v bajt kod virtualnoj mashiny ne principialno realizuyut staticheskuyu leksicheskuyu oblast vidimosti tak kak ona udobnee realizuetsya v kompilyatore Kompilyator rabotaet s leksicheskim kontekstom kotoryj statichen i ne menyaetsya pri ispolnenii programmy i obrabatyvaya obrashenie k imeni on mozhet legko opredelit adres v pamyati gde raspolagaetsya svyazannyj s imenem obekt Dinamicheskij kontekst nedostupen kompilyatoru tak kak on mozhet menyatsya v hode ispolneniya programmy ved odna i ta zhe funkciya mozhet vyzyvatsya vo mnozhestve mest prichyom ne vsegda yavno tak chto dlya obespecheniya dinamicheskoj oblasti vidimosti kompilyator dolzhen dobavit v kod dinamicheskuyu podderzhku opredeleniya obekta na kotoryj ssylaetsya identifikator Eto vozmozhno no snizhaet skorost raboty programmy trebuet dopolnitelnoj pamyati i uslozhnyaet kompilyator V sluchae s interpretiruemymi yazykami naprimer skriptovymi situaciya principialno inaya Interpretator obrabatyvaet tekst programmy neposredstvenno v moment ispolneniya i soderzhit vnutrennie struktury podderzhki ispolneniya v tom chisle tablicy imyon peremennyh i funkcij s realnymi znacheniyami i adresami obektov Interpretatoru proshe i bystree vypolnit dinamicheskoe svyazyvanie prostym linejnym poiskom v tablice identifikatorov chem postoyanno otslezhivat leksicheskuyu oblast vidimosti Poetomu interpretiruemye yazyki chashe podderzhivayut dinamicheskoe svyazyvanie imyon Osobennosti svyazyvaniya imyonV ramkah kak dinamicheskogo tak i leksicheskogo podhoda k svyazyvaniyu imyon mogut byt nyuansy svyazannye s osobennostyami konkretnogo yazyka programmirovaniya ili dazhe ego realizacii V kachestve primera rassmotrim dva Si podobnyh yazyka programmirovaniya JavaScript i Go Yazyki sintaksicheski dovolno blizki i oba ispolzuyut leksicheskuyu oblast vidimosti no tem ne menee razlichayutsya detalyami eyo realizacii Nachalo oblasti vidimosti lokalnogo imeni V sleduyushem primere pokazany dva tekstualno analogichnyh fragmenta koda na JavaScript i Go V oboih sluchayah v globalnoj oblasti vidimosti obyavlyaetsya peremennaya scope inicializirovannaya strokoj global a v funkcii f snachala vypolnyaetsya vyvod znacheniya scope zatem lokalnoe obyavlenie peremennoj s tem zhe imenem inicializirovannoe strokoj local i nakonec povtornyj vyvod znacheniya scope Dalee privedyon realnyj rezultat vypolneniya funkcii f v kazhdom sluchae JavaScript Govar scope global function f alert scope var scope local alert scope var scope global func f fmt Println scope var scope local fmt Println scope undefined local global local Legko videt chto raznica zaklyuchaetsya v tom kakoe znachenie vyvoditsya v stroke pomechennoj kommentariem so znakom voprosa V JavaScript oblastyu vidimosti lokalnoj peremennoj yavlyaetsya vsya funkciya v tom chisle ta eyo chast kotoraya nahoditsya do obyavleniya pri etom inicializaciya etoj peremennoj vypolnyaetsya tolko v moment obrabotki stroki gde ona nahoditsya Na moment pervogo vyzova alert scope lokalnaya peremennaya scope uzhe sushestvuet i dostupna no eshyo ne poluchila znacheniya to est po pravilam yazyka imeet specialnoe znachenie undefined Imenno poetomu v pomechennoj stroke budet vyvedeno undefined V Go ispolzuetsya bolee tradicionnyj dlya etogo tipa yazykov podhod soglasno kotoromu oblast vidimosti imeni nachinaetsya so stroki gde ono obyavlyaetsya Poetomu vnutri funkcii f no do obyavleniya lokalnoj peremennoj scope eta peremennaya nedostupna i pomechennaya znakom voprosa komanda vyvodit znachenie globalnoj peremennoj scope to est global Blochnaya vidimost Eshyo odin nyuans v semantike leksicheskoj oblasti vidimosti nalichie ili otsutstvie tak nazyvaemoj blochnoj vidimosti to est vozmozhnosti obyavit lokalnuyu peremennuyu ne tolko vnutri funkcii procedury ili modulya no i vnutri otdelnogo bloka komand v Si podobnyh yazykah zaklyuchyonnogo v figurnye skobki Dalee privedyon primer identichnogo koda na dvuh yazykah dayushego raznye rezultaty vypolneniya funkcii f JavaScript Gofunction f var x 3 alert x for var i 10 i lt 30 i 10 var x i alert x alert x func f var x 3 fmt Println x for i 10 i lt 30 i 10 var x i fmt Println x fmt Println x 3 10 20 20 3 10 20 3 Raznica proyavlyaetsya v tom kakoe znachenie budet vyvedeno poslednim operatorom v funkcii f pomechennym znakom voprosa v kommentarii V JavaScript net blochnoj oblasti vidimosti v versiyah predshestvuyushih ES6 a povtornoe obyavlenie lokalnoj peremennoj rabotaet prosto kak obychnoe prisvaivanie Prisvaivanie x znachenij i vnutri cikla for izmenyaet edinstvennuyu lokalnuyu peremennuyu x kotoraya byla obyavlena v nachale funkcii Poetomu posle zaversheniya cikla peremennaya x sohranyaet poslednee znachenie prisvoennoe ej v cikle Eto znachenie i vyvoditsya v rezultate V Go blok operatorov obrazuet lokalnuyu oblast vidimosti i obyavlyaemaya vnutri cikla peremennaya x eto novaya peremennaya oblastyu vidimosti kotoroj yavlyaetsya tolko telo cikla ona perekryvaet x obyavlennuyu v nachale funkcii Eta dvazhdy lokalnaya peremennaya poluchaet v kazhdom prohode cikla novoe znachenie i vyvoditsya no eyo izmeneniya ne zatragivayut obyavlennuyu vne cikla peremennuyu x Posle zaversheniya cikla obyavlennaya v nyom peremennaya h prekrashaet svoyo sushestvovanie a pervaya x stanovitsya snova vidna Eyo znachenie ostayotsya prezhnim ono i vyvoditsya v rezultate Vidimost i sushestvovanie obektovNe sleduet otozhdestvlyat vidimost identifikatora s sushestvovaniem znacheniya s kotorym dannyj identifikator svyazan Na sootnoshenie vidimosti imeni i sushestvovaniya obekta vliyaet logika programmy i klass pamyati obekta Dalee neskolko tipichnyh primerov Dlya peremennyh pamyat pod kotorye vydelyaetsya i osvobozhdaetsya dinamicheski v kuche vozmozhno lyuboe sootnoshenie vidimosti i sushestvovaniya Peremennaya mozhet byt obyavlena i zatem inicializirovana togda obekt sootvetstvuyushij imeni fakticheski poyavitsya pozzhe vhozhdeniya v oblast vidimosti No obekt mozhet byt sozdan zaranee sohranyon i zatem prisvoen peremennoj to est poyavitsya ranshe To zhe i s udaleniem posle vyzova komandy udaleniya dlya peremennoj svyazannoj s dinamicheskim obektom sama peremennaya ostayotsya vidimoj no eyo znachenie ne sushestvuet a obrashenie k nemu privedyot k nepredskazuemym rezultatam S drugoj storony esli komanda udaleniya ne vyzvana to obekt v dinamicheskoj pamyati mozhet prodolzhat sushestvovat i posle togo kak ssylayushayasya na nego peremennaya vyshla iz oblasti vidimosti Dlya lokalnyh peremennyh so staticheskim klassom pamyati v yazykah Si i C znachenie poyavlyaetsya logicheski v moment zapuska programmy Pri etom imya nahoditsya v oblasti vidimosti tolko pri ispolnenii soderzhashej ego funkcii Prichyom v promezhutkah mezhdu funkciyami znachenie sohranyaetsya Avtomaticheskie v terminologii Si peremennye sozdavaemye pri vhode v funkciyu i unichtozhaemye pri vyhode sushestvuyut v period vremeni kogda ih imya vidno To est dlya nih vremena dostupnosti i sushestvovaniya prakticheski mozhno schitat sovpadayushimi PrimerySi Nachinaetsya globalnaya oblast vidimosti int countOfUser 0 int main S etogo momenta obyavlyaetsya novaya oblast vidimosti v kotoroj vidna globalnaya int userNumber 10 include lt stdio h gt int a 0 globalnaya peremennaya int main printf d a budet vyvedeno chislo 0 int a 1 obyavlena lokalnaya peremennaya a globalnaya peremennaya a ne vidna printf d a budet vyvedeno chislo 1 int a 2 eshe lokalnaya peremennaya v bloke globalnaya peremennaya a ne vidna ne vidna i predydushaya lokalnaya peremennaya printf d a budet vyvedeno chislo 2 PrimechaniyaSpecifikaciya yazyka HTML Arhivnaya kopiya ot 4 dekabrya 2012 na Wayback Machine perevodchik A Piramidin intuit ru ISBN 978 5 94774 648 8 17 Lekciya Formy Oblasti vidimosti neopr Data obrasheniya 11 marta 2013 Arhivirovano 26 noyabrya 2019 goda

NiNa.Az

NiNa.Az - Абсолютно бесплатная система, которая делится для вас информацией и контентом 24 часа в сутки.
Взгляните
Закрыто