В информатике локальная переменная — это переменная , которой задана локальная область видимости . Ссылка на локальную переменную в функции или блоке , в котором она объявлена, переопределяет то же имя переменной в большей области видимости. В языках программирования, имеющих только два уровня видимости, локальные переменные противопоставляются глобальным переменным . С другой стороны, многие языки, производные от ALGOL, допускают любое количество вложенных уровней видимости, при этом частные переменные, функции, константы и типы скрыты внутри них, либо вложенными блоками, либо вложенными функциями . Локальные переменные имеют основополагающее значение для процедурного программирования , и в более общем смысле модульного программирования : переменные локальной области видимости используются для предотвращения проблем с побочными эффектами , которые могут возникнуть с глобальными переменными .
Локальные переменные могут иметь лексическую или динамическую область действия , хотя лексическая (статическая) область действия встречается гораздо чаще. В лексической области действия (или лексической области действия; также называемой статической областью действия или статической областью действия), если областью действия имени переменной является определенный блок, то ее областью действия является текст программы определения блока: внутри текста этого блока имя переменной существует и связано со значением переменной, но вне текста этого блока имя переменной не существует. Напротив, в динамической области действия (или динамической области действия), если областью действия имени переменной является определенный блок, то ее областью действия является этот блок и все функции, транзитивно вызываемые этим блоком (за исключением случаев повторного переопределения другим объявлением); после завершения блока имя переменной не существует. Некоторые языки, такие как Perl и Common Lisp , позволяют программисту выбирать статическую или динамическую область действия при определении или переопределении переменной. Примерами языков, использующих динамическую область видимости, являются Logo , Emacs lisp , а также языки оболочек bash , dash и "локальное" объявление оболочки MirBSD Korn ( mksh ). Большинство других языков предоставляют лексически ограниченные локальные переменные.
В большинстве языков локальные переменные являются автоматическими переменными, хранящимися непосредственно в стеке вызовов . Это означает, что когда рекурсивная функция вызывает себя, локальным переменным в каждом экземпляре функции присваиваются отдельные адреса . Следовательно, переменные этой области действия могут быть объявлены, записаны и прочитаны без какого-либо риска побочных эффектов для функций за пределами блока, в котором они объявлены.
Языки программирования, использующие семантику вызова по значению , предоставляют вызываемой подпрограмме ее собственную локальную копию переданных ей аргументов . В большинстве языков эти локальные параметры обрабатываются так же, как и другие локальные переменные внутри подпрограммы. Напротив, семантика вызова по ссылке и вызова по имени позволяет параметрам действовать как псевдонимы значений, переданных в качестве аргументов, что позволяет подпрограмме изменять переменные за пределами ее собственной области действия.
Специальный тип локальной переменной, называемый статической локальной, доступен во многих основных языках (включая C / C++ , Visual Basic , VB.NET и PHP ), который позволяет сохранять значение от одного вызова функции к другому – это статическая переменная с локальной областью действия. В этом случае рекурсивные вызовы функции также имеют доступ к (единственной, статически выделенной ) переменной. Во всех вышеперечисленных языках статические переменные объявляются как таковые с помощью специального ключевого слова класса хранения (например, static
).
Статические локальные переменные в глобальных функциях имеют такое же время жизни, как и статические глобальные переменные , поскольку их значение остается в памяти на протяжении всего срока службы программы [1], но имеют область действия функции (а не глобальную область действия), как и автоматические локальные переменные.
Это отличается от других случаев использования static
ключевого слова , которое имеет несколько разных значений в разных языках.
Perl поддерживает как динамические, так и лексически-областные локальные переменные. Ключевое слово local
используется для определения локальных динамически-областных переменных, в то время как my
используется для локальных лексически-областных переменных. Поскольку динамическая область видимости сегодня встречается реже, документация Perl предупреждает, что « local
не то, что большинство людей считают «локальной».». [2] Вместо этого local
ключевое слово дает временное, динамически-областное значение глобальной (пакетной) переменной, которое сохраняется до конца охватывающего блока. Однако переменная видна любой функции, вызываемой из блока. [3] Чтобы создать лексически-областные локальные переменные, используйте my
вместо этого оператор . [4]
Чтобы понять, как это работает, рассмотрим следующий код:
$a = 1 ; sub f () { local $a ; $a = 2 ; g (); } sub g () { print "$a\n" ; } g (); f (); g ();
это выведет:
121
Это происходит, поскольку глобальная переменная $a изменяется на новое временное (локальное) значение внутри f()
, но глобальное значение восстанавливается при выходе из области действия f()
.
Использование my
в этом случае вместо local
привело бы к выводу 1 три раза, поскольку в этом случае $a
переменная была бы ограничена статической областью действия функции f()
и не была бы видна g()
.
Рэндал Л. Шварц и Том Феникс утверждают, что оператор local
должен был иметь другое имя, например save
. [5]
Ruby как язык также был вдохновлен Perl, но в этом случае нотация была сделана проще: имя глобальной переменной должно предваряться знаком $, как $variable_name
, в то время как локальная переменная просто не имеет знака $ перед своим именем, как variable_name
(в то время как в Perl все скалярные значения имеют $ впереди). Обратите внимание, что Ruby предоставляет только встроенную поддержку статически-областных локальных переменных, как в Perl my
, но не динамически-областных локальных переменных, как в Perl local
. Существует по крайней мере одна библиотека для Ruby, которая предоставляет динамически-областные переменные. [6]