月ノ書

<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 は隠れてしまいます

ローカルとグローバルを使い分ける理由

「じゃあ全部グローバル変数にすればいいのでは?」と思う人もいるかもしれません。確かに、どこからでもアクセスできて便利そうに見えますが、グローバル変数には以下のデメリットがあります

グローバル変数のデメリット

処理速度が遅くなる

ローカル変数は「スタック領域」に置かれるので、アクセスが速いですが、グローバル変数は「静的領域」に置かれるため、環境によっては少し遅くなることがある

プログラムが複雑になる

どこからでも変更ができるので、「どこで値が変わったのかわからない」というデバッグ地獄になりがち

名前の衝突が起きやすい

たくさんのファイルで同じ変数名を使うと、意図せず値が上書きされる危険がある

再利用性が下がる

関数が「外の変数に依存」してしまうため、ほかのプロジェクトでそのまま使いまわすのが難しくなる

逆にローカル変数は必要な処理の中だけで使うから安全かつ、値が外から勝手に書き換えられないなどといった利点があります

学習進捗

0
Would love your thoughts, please comment.x