2012/06/19

C言語 ローカル、グローバル変数

同じ変数名を使って有効範囲を確かめてみる。C言語では有効範囲をスコープという。関数の外で宣言する変数をグローバル変数(外部変数)。関数内で宣言する変数をローカル変数(局所変数)という。ファイルを3つ用意して、それぞれの関数で表示させてみる。

ファイル1

#include <stdio.h>
/* グローバル変数の宣言 初期化はファイル2で行っている。*/
int var;
/* fun1 */
void func1(){
  printf("func1 %d\n", var);
}
/* fun2 */
void func2(){
  int var = 20;
  printf("func2 %d\n", var);
}
/* fun3 */
void func3(){
  {
    int var = 30;
    printf("func3 A %d\n", var);
  }
  printf("func3 B %d\n", var);
}
/* メイン関数 */
int main(){
  func1();
  func2();
  func3();
  func2();
  func4();
  func5();
  func6();
  return 0;
}

ファイル2

#include <stdio.h>
/* グローバル変数の初期化 */
int var = 10;
/* fun4 */
void func4(){
  printf("func4 %d\n", var);
}
/* fun5 */
void func5(){
  /* externはグローバル変数使用と宣言
  上部で宣言済みなので通常省略 */
  extern var;
  printf("func5 %d\n", var);
}

ファイル3

#include <stdio.h>
/* fun6 */
void func6(){
  extern var; /* グローバル変数使用 必須 */
  printf("func6 %d\n", var);
}
実行すると以下のようになる。
func1 10
func2 20
func3 A 30
func3 B 10
func2 20
func4 10
func5 10
func6 10
スコープ
変数の有効範囲は関数内に同じ名前の変数が宣言されていれば、それを優先させていることが分かる。さらに関数内のブロックで宣言した変数は、その中でしか有効ではない。狭い範囲で宣言したものが優先される。

グローバル変数の寿命
グローバル変数はプログラム実行時にメモリ上に作られ、プログラム終了時まで保持される。一方ローカル変数は通常関数を抜けた時点で破棄される。static宣言した場合はグローバル変数のように扱われる。

グローバル変数の宣言と初期化
サンプルのように複数ファイルにまたがって使用する場合は、いくつかの方法がある。まず1箇所で初期化を行う。初期化を行ったファイル内ではスコープの優先順位に沿って使えるようになる。

グローバル変数を他ファイルで利用
基本的に「ファイル3」のように「extern」を付けて宣言し扱う必要がある。もしくは「ファイル2」のように関数の外で、初期化を行わず宣言だけをしておく方法もある。

グローバル変数の利用はなるべく避ける
グローバル変数はある意味便利だが、可能な限り使わないほうがよい。個人で作る小さなプログラムではソースコードもシンプルになってよい面もあるが、関数の独立性がなくなって再利用しにくくなるし、バグが出た場合、追求するのが大変になってしまう。ローカル変数に置き換えられるものは可能な限りローカル変数にすべき。

C言語 ANSI C89 Meadow & MinGW GCC 目次