例えばiをmain関数内でのみ定義した場合、iはmain関数内でのみ使用でき、他の関数で使用することはできません。
/* mainでのみiを定義 */ #include <stdio.h> void sub(){ /* subではiが定義されていないので、iを使用することはできない。 */ puts("Sub"); } int main(int argc, char* argv[]){ /* iを定義 */ int i = 1; sub(): /* mainでiが定義されているので、main内ではiが使用可能 */ printf("Main %d\n",i); return 0; }
/* subでもiを定義 */ #include <stdio.h> void sub(){ /* iを定義 */ int i = 2; /* subでもiが定義されているので、iを使用することができる。 */ /* ただし、mainのiとsubのiは別物である。 */ printf("Sub %d\n",i); } int main(int argc, char* argv[]){ /* iを定義 */ int i = 1; sub(): /* mainでiが定義されているので、main内ではiが使用可能 */ printf("Main %d\n",i); return 0; }
これら、関数内で定義した、関数内でのみ有効な変数を局所変数(内部変数、ローカル変数)と呼びます。
一方、C言語では全ての関数で使用可能な変数を作成することができ、これを大域変数(外部変数、グローバル変数)と呼びます。大域変数の作成方法は簡単で、関数外で変数の定義をします。
#include <stdio.h> int i = 1; void sub(){ /* iを使用することができる。 */ printf("Sub %d\n",i); } int main(int argc, char* argv[]){ sub(): /* iが使用可能 */ printf("Main %d\n",i); return 0; }
/* 途中でiの値を変更する例 */ #include <stdio.h> int i = 1; void sub(){ /* iを使用することができる。 */ printf("Sub %d\n",i); /* iの値を変更 */ i++; } int main(int argc, char* argv[]){ sub(): /* iが使用可能(iの値はsub()内で変更されている) */ printf("Main %d\n",i); return 0; }
また、大域変数と局所変数とで名前がかぶった場合、局所変数が優先されます。
#include <stdio.h> int i = 1; void sub(){ /* iは大域変数 */ printf("Sub %d\n",i); /* iの値を変更 */ i++; } void sub2(int i){ /* iは引数 */ printf("Sub2 %d\n",i); } int main(int argc, char* argv[]){ /* main内でiを定義 */ int i = 2; sub(): sub2(6); /* iは局所変数 */ printf("Main %d\n",i); return 0; }
大域変数はどの関数内でも使用できるため使い勝手がいいですが、どこからでも値の変更ができてしまい、乱用すると思わぬバグが発生することがあります。使用時にはその目的を明確にしておきましょう。