スコープ 基礎編第16回


20140218

変数の回に説明したように、データは変数(物理的にはメモリ)に格納されます。プログラムはこの変数を処理しますが、変数には有効範囲(スコープ)があるため、すべてのプログラムが変数を利用できるわけではありません。

スコープについて

宣言された変数の有効範囲をスコープ(scope)と呼びます。スコープが適用されるのは変数に限りません。別の回で説明しますが、関数(メソッド)にもスコープがあります。この回では変数のスコープについて説明します。

変数にはそのスコープに応じてグローバル変数ローカル変数があります。

  • グローバル変数: 関数の外部に定義され、プログラム内のどこからでも参照可。
  • ローカル変数: 関数内で定義され、その関数内でのみ使用可能。

変数に参照が可能ということは、その変数にアクセスして格納している値を利用することができるという意味です。

図で示すと次のようになります。

スコープ

メインルーチンと関数Aは関数Bのローカル変数Yを利用できず、同様にメインルーチンと関数Bは関数Aのローカル変数Xを利用できません。ローカル変数はそれを宣言したサブルーチン(関数)内でのみ有効であり、サブルーチン外に処理が戻る(あるいは関数の処理が終了する)と破棄されます。例えば、関数Aでローカル変数nCounterを宣言し、関数Bで同じ名前nCounterを使って変数を宣言しても何も問題はありません。有効範囲がそれぞれの関数内に限定されるためです。変数名やデータ型が同じであっても、異なる関数内で宣言されていれば違う変数になります。

グローバル変数は関数Aや関数Bから利用することができます。通常、グローバル変数はメインルーチン内で宣言され、プログラム全体で利用でき、プログラムが終了するまで有効のままです。小さなプログラムの場合、必要な数だけ変数を宣言しさえすれば、後は自由に利用できるという点で便利です。プログラムが大きくなると変数の数も増えますので、グローバル変数だけでは効率が悪くなります。どこからでも利用できるということは、どの時点で変数が利用され、どのように変化し、現在どの値になっているかを把握しにくくなります。カウンタのように一時的に利用されるだけの値を不要になった後も保持するのは無駄です。

では、グローバル変数とローカル変数に同じ名前をつけることはできるのでしょうか。

結論から言うと、同じ名前をつけることができます。この場合、関数内ではグローバル変数が遮蔽されローカル関数が使用されます。グローバル変数を使用したい場合、グローバル解決演算子(::)を変数の前につけます(C++の場合)。

さらに、ローカル変数をグローバル変数と同じようにプログラムが終了するまで保持することもできます。C++の場合、staticを頭に付けて付けて変数を宣言します(「static int x;」など)。

ローカルかグローバルかを指定する方法は言語によって異なりますので注意してください。Javaのようにグローバル変数がないプログラミング言語もあり、接頭辞で区別する言語もあります。それぞれのリファレンスを参照してください。

まとめ

小さなプログラムのときはそれほど意識することはありませんが、少し大きいプログラムを作成したり、サブルーチンや関数を作成したりする場合は変数のスコープを意識する必要があります。スコープについては、クラスの回でさらに説明します。

グローバル変数とローカル変数の違いを理解する最も良い方法は、実際にプログラムを書いてみることです。

この講座も後半に突入して内容も難しくなっていると思います。説明不足の点もあると思いますので、不明な点はご指摘ください。

次回は、配列について説明する予定です。

では、また。

コメントしてみる