例えば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;
}
大域変数はどの関数内でも使用できるため使い勝手がいいですが、どこからでも値の変更ができてしまい、乱用すると思わぬバグが発生することがあります。使用時にはその目的を明確にしておきましょう。