内 容
- ローカル変数とグローバル変数
ローカル変数とグローバル変数
同じ変数名を使う・ローカル変数とスコープ
ある関数で定義した変数名を別の関数でも利用したいときがあります。例えば、答えを意味するansであったり、値を意味するvalueなどは多くの関数で利用される可能性がある変数名です。では、一つのプログラムの中で同じ変数名を利用することはできるのでしょうか。
次のプログラムは、main関数で定義されている変数名aと同じ変数名が別の関数funcでも定義されている例です。どちらの変数も関数のコードブロック{}内で定義されています。このように、コードブロック内で定義される変数は、その有効範囲がそのコードブロック内に限定されます。このような変数を
ローカル変数(local variable)と呼びます。また、この有効範囲のことを
スコープ(scope)と呼びます。
samename.c
#include <stdio.h>
void func(void);
int main(void)
{
int a = 222;
printf("main:a = %d\n", a);
func();
return 0;
}
void func(void)
{
int a = 333;
printf("func:a = %d\n", a);
}
このプログラムを実行して、それぞれローカル変数aが別の変数として扱われていることを確認しましょう。
ブロック内変数(ローカル変数)
関数で定義されている変数名と同じ変数名がその中のコードブロック{}内で定義されている場合はどうなるでしょう。
次のプログラムは、main関数で定義されているローカル変数aと同じ変数名が、同じ関数内のfor文のコードブロック内で定義されている例です。for文内で定義されている変数aのスコープはfor文のコードブロック内のみとなり、main関数で定義されている変数aよりも優先されます。
samename2.c
#include <stdio.h>
void func(void);
int main(void)
{
int i;
int a = 222; //ローカル変数
printf("main:a = %d\n", a);
func();
for(i=0; i<3; i++){
int a = 444; //ブロック内変数(ローカル変数)
printf("for: a = %d\n",a);
}
return 0;
}
void func(void)
{
int a = 333; //ローカル変数
printf("func:a = %d\n", a);
}
関数の引数はローカル変数
関数のコードブロック内ではなく、その引数に同じ変数名が使われている場合はどうなるでしょうか。
次のプログラムは関数func2の引数に、呼び出し側であるmain関数で定義されている変数と同じ変数名aが使われている例です。引数はその定義されている関数内でのみ有効となるローカル変数として扱われます。したがって、下記のプログラムを実行すると、main関数で呼び出された関数func2()は引数aで受け取った値555をローカル変数であるaとして表示していることが確認できます。
samename3.c
#include <stdio.h>
void func(void);
void func2(int a);
int main(void)
{
int i;
int a = 222; //ローカル変数
printf("main:a = %d\n", a);
func();
for(i=0; i<3; i++){
int a = 444; //ブロック内変数(ローカル変数)
printf("for: a = %d\n",a);
}
func2(555);
return 0;
}
void func(void)
{
int a = 333; //ローカル変数
printf("func:a = %d\n", a);
}
void func2(int a){ //引数もローカル変数
printf("func2:a = %d\n",a);
}
グローバル変数
関数の外で宣言された変数を
グローバル変数(global variable)と言います。ローカル変数のスコープがコードブロック内に限定されるのに対して、グローバル変数のスコープはプログラム全体(一つのファイル内)となります。
globaAndLocal.c
#include <stdio.h>
/* プロトタイプ宣言 */
void func1(void);
void func2(void);
int glb; //グローバル変数
/* メイン関数 */
int main(void)
{
int loc; //ローカル変数
glb = 999;
loc = 888;
printf("main glb = %d¥n", glb);
printf("main loc = %d¥n", loc);
func1();
func2();
return 0;
}
/* ユーザ定義関数 */
void func1(void)
{
int loc; //ローカル変数
loc = 111;
printf("func1 glb = %d¥n", glb);
printf("func1 loc = %d¥n", loc);
}
void func2(void)
{
int loc; //ローカル変数
loc = 222;
printf("func2 glb = %d¥n", glb);
printf("func2 loc = %d¥n", loc);
}
上記のプログラム例では、変数glbがグローバル変数で、変数locがローカル変数になります。ローカル変数locはmain関数、func1関数、func2関数の各関数で定義されていますが、それぞれ宣言された関数の中だけで有効となります。
- グローバル変数はプログラム全体を通して有効である。
- ローカル変数は宣言されたそのブロック内だけで有効である。
- グローバル変数とローカル変数が同一の名前だった場合は、そのブロック内で宣言されたローカル変数が優先される。
- 仮引数はローカル変数として扱われる。
グローバル変数は危険な変数
グローバル変数はプログラムのどこからでも利用することができるため、大変都合が良い変数です。しかし、グローバル変数とローカル変数は適切に使い分けなければ、大きなトラブルの元となります。
- グローバル変数と同じ名前をブロック内で付けてしまい、ローカル変数なのかグルーバル変数なのか区別せずに利用してしまう。
- グローバル変数はプログラムのどこからでも書き換えが可能である。もし、間違った書き換えが行われた際、それがどこで生じたことなのかをプログラム全体から探し出すことは大変な作業になる。
グローバル変数は原則禁止!ほとんどの問題はローカル変数で対応できる!
expand_lessBack to TOP