ローカル変数とは
ローカル変数(局所変数)とは、プログラムのある特定の部分、例えば関数やブロック内でのみ有効な変数のことです。
グローバル変数(大域変数)とは対照的に、ローカル変数はその定義された範囲内でのみ参照や操作が可能です。この限定された有効範囲を「スコープ」と呼びます。
ローカル変数の定義や扱いは
プログラミング言語によって異なります。ここでは
C言語と
Javaを例に、ローカル変数の詳細について解説します。
C言語におけるローカル変数
C言語では、「ローカル変数」という用語が規格で明示的に使用されているわけではありませんが、関数内のブロック内で定義された変数は、そのブロック内でのみ参照可能です。これを便宜上ローカル変数と呼びます。
C99以前の規格では、ローカル変数はブロックの先頭でのみ定義可能でしたが、
C99以降では、
C++と同様にブロック内の任意の位置で定義できるようになりました。
スコープとライフタイム
ローカル変数のスコープは、変数が宣言された場所から、その変数が定義されたブロックを抜けるまでです。スコープ外からは変数を参照できません。異なる関数(異なるブロック)で同じ名前のローカル変数を定義しても、互いに影響しません。
c
void function() {
int i = 0; // ローカル変数 i のスコープはここから
{
int j = 1; // ローカル変数 j のスコープはここから
// j はここで有効
} // j のスコープはここまで
// i はここで有効
} // i のスコープはここまで
ローカル変数のライフタイム(寿命)は、デフォルトではその変数を定義したブロックを抜けるまでです。変数は宣言時に自動的にメモリが割り当てられ、ブロックを抜けると自動的にメモリが解放されます。このため、ローカル変数は「自動変数」とも呼ばれます。未初期化の自動変数の内容は不定です。
静的ローカル変数
ローカル変数宣言に `static` キーワードを付加すると、「静的ローカル変数」となり、変数のライフタイムはプログラムの実行期間全体になります。
C言語では、静的ローカル変数はプログラム開始前に一度だけ初期化されますが、
C++では変数の定義箇所に最初に到達した際に初期化されます。
c++
void func() {
static int count = 0; // 静的ローカル変数
count++;
// ...
}
静的ローカル変数は、関数の呼び出し間で値を保持したい場合に便利です。
C++におけるローカル変数の応用
C++では、静的ローカル変数がSingletonパターンで利用されることがあります。また、
C++では変数のライフタイムが終了するときにデストラクタが呼ばれるため、
RAII(Resource Acquisition Is Initialization)というデザインパターンが利用できます。これにより、リソースの解放などの後始末処理が確実に行えます。
Javaにおけるローカル変数
Javaにおける変数は、
インスタンス変数、クラス変数、ローカル変数、仮
引数の4種類に大別されます。ここでいうローカル変数は、メソッド内で宣言された変数のことを指します。
スコープとライフタイム
Javaのローカル変数のスコープとブロックの概念はC/
C++とほぼ同様です。ただし、
Javaでは静的ローカル変数を定義することはできません。
java
public void method() {
int i = 0; // ローカル変数 i のスコープはここから
{
int j = 1; // ローカル変数 j のスコープはここから
// j はここで有効
} // j のスコープはここまで
// i はここで有効
} // i のスコープはここまで
Javaでは、ローカル変数に既定値は割り当てられません。そのため、初期化せずにアクセスしようとするとコンパイルエラーとなります。C/
C++では未初期化のローカル変数へのアクセスは未定義動作を引き起こすものの、コンパイル自体は通ってしまうのと対照的です。
メモリ管理
Javaのメモリ解放は
ガベージコレクションによって行われます。ローカル変数はスタック領域に確保されますが、クラスや
配列などの参照型の場合、オブジェクト本体はヒープ領域に作成されます。ローカル変数のライフタイムが終了しても、その変数が指していたオブジェクトが直ちにメモリから解放されるとは限りません。
まとめ
ローカル変数は、プログラムの特定の範囲内でのみ有効な変数であり、コードの可読性や保守性を高める上で重要な役割を果たします。
C言語、
C++、
Javaなどの
プログラミング言語では、ローカル変数の定義や振る舞いに違いがあるため、各言語の特性を理解して適切に利用することが重要です。