コンピュータサイエンスでは、ローカル変数はローカルスコープを与えられた変数です。ローカル変数が宣言された関数またはブロック内のローカル変数参照は、より大きなスコープ内の同じ変数名を上書きします。可視性のレベルが 2 つしかないプログラミング言語では、ローカル変数はグローバル変数と対比されます。一方、ALGOLから派生した多くの言語では、任意の数のネストされた可視性レベルが許可されており、プライベート変数、関数、定数、型は、ネストされたブロックまたはネストされた関数によってその中に隠されています。ローカル変数は手続き型プログラミング、より一般的にはモジュール型プログラミングの基本です。ローカルスコープの変数は、グローバル変数で発生する可能性のある副作用の問題を回避するために使用されます。
ローカル変数には、字句スコープまたは動的スコープを設定できますが、字句スコープ(静的スコープ)の方がはるかに一般的です。字句スコープ(または静的スコープとも呼ばれます)では、変数名のスコープが特定のブロックである場合、そのスコープはブロック定義のプログラムテキストになります。つまり、そのブロックのテキスト内では変数名が存在し、変数の値にバインドされますが、そのブロックのテキスト外では変数名は存在しません。一方、動的スコープ(または動的スコープ)では、変数名のスコープが特定のブロックである場合、そのスコープはそのブロックと、そのブロックによって推移的に呼び出されるすべての関数(別の宣言によって再度オーバーライドされる場合を除く)になります。ブロックが終了すると、変数名は存在しません。PerlやCommon Lispなどの一部の言語では、プログラマが変数を定義または再定義する際に、静的スコープまたは動的スコープを選択できます。動的スコープを使用する言語の例としては、Logo、Emacs Lisp、シェル言語のbash、dash、およびMirBSD Kornシェル(mksh)の「local」宣言などが挙げられます。その他のほとんどの言語では、字句スコープのローカル変数が提供されています。
ほとんどのプログラミング言語では、ローカル変数は自動変数であり、呼び出しスタックに直接格納されます。つまり、再帰関数が自身を呼び出す際、関数の各インスタンス内のローカル変数にはそれぞれ異なるアドレスが割り当てられます。したがって、このスコープの変数は、宣言されたブロック外の関数に副作用を与えることなく、宣言、書き込み、読み取りを行うことができます。
値渡しセマンティクスを採用するプログラミング言語では、呼び出されたサブルーチンは、渡された引数のローカルコピーを保持します。ほとんどの言語では、これらのローカルパラメータは、サブルーチン内の他のローカル変数と同様に扱われます。これに対し、参照渡しセマンティクスと名前渡しセマンティクスでは、パラメータは引数として渡された値のエイリアスとして機能するため、サブルーチンは自身のスコープ外の変数を変更できます。
多くの主流言語( C / C++、Visual Basic、VB.NET、PHPなど)には、静的ローカル変数と呼ばれる特殊なタイプのローカル変数があり、関数の呼び出し間で値を保持できます。これはローカルスコープを持つ静的変数です。この場合、関数の再帰呼び出しでも(単一の静的に割り当てられた)変数にアクセスできます。上記のすべての言語では、静的変数は特別なストレージクラスキーワード(例:)を使用して宣言されます。static
グローバル関数内の静的ローカル変数は、その値がプログラムの実行中メモリに保持されるため、静的グローバル変数と同じ寿命を持ちますが、自動ローカル変数と同様に関数スコープを持ちます(グローバルスコープではありません)。[ 1 ]
staticこれは、様々な言語で複数の異なる意味を持つキーワードの他の用法とは異なります。
Perl は、動的スコープと字句スコープの両方のローカル変数をサポートしています。キーワードはlocal動的スコープのローカル変数を定義するために使用され、はmy字句スコープのローカル変数に使用されます。動的スコープは現在ではあまり一般的ではないため、Perl のドキュメントでは「localは、ほとんどの人が考える「ローカル」ではありません」と警告しています。[ 2 ] 代わりに、キーワードは、囲んでいるブロックの終了まで有効な、一時的な動的スコープのlocal値をグローバル (パッケージ) 変数に与えます。ただし、この変数は、ブロック内から呼び出されたすべての関数から参照できます。[ 3 ] 字句スコープのローカル変数を作成するには、代わりに演算子を使用します。[ 4 ]my
その仕組みを理解するために、以下のコードを参考にしてください。
$a = 1 ; sub f () { local $a ; $a = 2 ; g (); } sub g () { print "$a\n" ; } g (); f (); g ();これは以下を出力します。
1 2 1
これは、グローバル変数 $a が内部で新しい一時的な(ローカル) 意味に変更されるf()が、のスコープを抜けるとグローバル値が復元されるためですf()。
myこの場合、の代わりにを使用すると、変数が関数の静的スコープに限定され、からは見えないlocalため、1 が 3 回出力されます。Randal L. Schwartz と Tom Phoenix は、演算子にはのような別の名前が付けられるべきだった と主張しています。[ 5 ]$af()g()localsave
Rubyという言語も Perl から影響を受けていますが、この場合、表記法はよりシンプルになっています。グローバル変数名には$ 記号を前に付ける必要$variable_nameがあり、 例:variable_namemylocal
local()my()