<C言語>スコープ
今回の記事でわかること
- 変数の「有効範囲(スコープ)」が分かる
- ローカル変数とグローバル変数の違いが分かる
スコープとは
スコープとは、変数が「どこで使えるか(有効範囲)」を表すもので、C言語では、宣言した場所によって変数が使える範囲が決まるというルールがあります
大きく分けると次の2種類があります
種類 | 説明 | 宣言場所 | 使用できる範囲 |
---|---|---|---|
ローカル変数 | 関数内で宣言する変数 | 関数やブロック内 | そのブロック内のみ |
グローバル変数 | 関数外で宣言する変数 | ファイルの先頭など | プログラム全体 |
ローカル変数
関数の中で宣言した変数は、その関数の中でしか使えません。そのような変数をローカル変数といいます
#include <stdio.h>
void hello() {
int x = 10; // ローカル変数
printf("hello内: x = %d\n", x);
}
int main(void) {
int y = 20; // ローカル変数
printf("main内: y = %d\n", y);
hello();
// printf("%d", x); // ←エラー!helloのxはmainからは見えない
return 0;
}
/* 出力結果
main内: y = 20
hello内: x = 10
*/
x は hello 内でしか使えず、 y は main の中でしか使えません。これがスコープの違いです
グローバル変数
関数の外で宣言した変数は、プログラム全体で使えます。これをグローバル変数といいます
#include <stdio.h>
int g = 100; // グローバル変数
void func() {
printf("funcから g = %d\n", g);
}
int main(void) {
printf("mainから g = %d\n", g);
func();
return 0;
}
/* 出力結果
mainから g = 100
funcから g = 100
*/
どの関数からも同じ g にアクセスできます
同じ名前に注意!
ローカル変数とグローバル変数で同じ名前を付けると、ローカル変数が優先されます
#include <stdio.h>
int num = 10; // グローバル変数
int main(void) {
int num = 20; // ローカル変数
printf("num = %d\n", num);
return 0;
}
/* 出力結果
num = 20
*/
この場合、main 内ではローカル変数 num が使われ、グローバル変数の num は隠れてしまいます
ローカルとグローバルを使い分ける理由
「じゃあ全部グローバル変数にすればいいのでは?」と思う人もいるかもしれません。確かに、どこからでもアクセスできて便利そうに見えますが、グローバル変数には以下のデメリットがあります
グローバル変数のデメリット
処理速度が遅くなる
ローカル変数は「スタック領域」に置かれるので、アクセスが速いですが、グローバル変数は「静的領域」に置かれるため、環境によっては少し遅くなることがある
プログラムが複雑になる
どこからでも変更ができるので、「どこで値が変わったのかわからない」というデバッグ地獄になりがち
名前の衝突が起きやすい
たくさんのファイルで同じ変数名を使うと、意図せず値が上書きされる危険がある
再利用性が下がる
関数が「外の変数に依存」してしまうため、ほかのプロジェクトでそのまま使いまわすのが難しくなる
逆にローカル変数は必要な処理の中だけで使うから安全かつ、値が外から勝手に書き換えられないなどといった利点があります