目的
変数の種類とスコープについて理解すること。
変数の種類
変数には大きく分けて、次の2種類があります。
- ローカル変数
- グローバル変数
今まで扱ってきた変数は、すべてローカル変数です。
ローカル変数とは
ローカル変数は、基本的にブロック {} の先頭で宣言します。
そして、宣言したブロック内部のみで利用が可能です。
例1
main 関数の中で宣言したものは、その外では使用できません。
void hoge(){
printf("%d\n", a); // コンパイルエラー
}
int main(){
int a;
a = 256;
hoge();
return 0;
}
例2
このように if 文の中でも宣言できます。
同名の変数がある場合、一番内側で宣言されたものが使用されます。
int a = 2; // このように変数は宣言時に初期化できます
if(1){
int a = 4;
printf("%d\n", a); // 4 が表示される
}
例3
関数に渡した引数は、その関数内部のみで利用可能な変数に代入されています。
void hoge(int a){ // a は関数 hoge 内部でのみ有効
a = 1024;
}
int main(){
int a = 512;
hoge(a);
printf("%d\n", a); // 512 が表示される
return 0;
}
グローバル変数
プログラムのどこからでも利用できる変数を、グローバル変数といいます。
グローバル変数は便利ですが、バグの原因になりやすいため使用は慎重に行います。
グローバル変数はローカル変数とは違い、自動的にゼロで初期化されます。
また、グローバル変数の宣言は、すべての関数の外側で行います。
例
int count; // グローバル変数の宣言
void increment(){
++count;
}
int main(){
printf("%d\n", count); // 0
increment();
printf("%d\n", count); // 1
return 0;
}
課題
課題1
出力される数値を予想しなさい。
また、実際に実行してその予想が正しかったのか確認しなさい。
int g;
void func(int a, int g){
printf("%d\n", g);
printf("%d\n", a);
++g;
}
int main(){
int a = g;
{ // ブロック、if(1){ ~ } と同じ意味です
int a = 1;
printf("%d\n", g);
printf("%d\n", a);
func(g, a);
}
printf("%d\n", g);
printf("%d\n", a);
return 0;
}
課題2
グローバル変数を用いて、次のようなプログラムを作りなさい。
- プログラムは初期値がゼロの整数を保持している
- ユーザーが ++ と入力したら、その整数をインクリメントする
- ユーザーが -- と入力したら、その整数をデクリメントする
- インクリメント、デクリメントの際に現在保持している整数を表示する
- ユーザーの入力は n 回行われる
このプログラムでは、次の変数及び関数を必ず用いること
もちろん、これ以外の変数や関数も自由に用いてよい。
- グローバル変数 current
整数の保持に使用する。 - 関数 increment, decrement
インクリメント、デクリメント処理はこの関数で行う。
次のプロトタイプ宣言で表される。void increment(); void decrement();
実行例
1行目はユーザーの入力の個数 n。
以降、入力のたびに保持している整数を出力すること。
./a.out 4 ++ 1 ++ 2 ++ 3 ++ 4
./a.out 4 -- -1 -- -2 ++ -1 ++ 0