Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語のスコープルール徹底解説!グローバル変数とローカル変数の違いとは

C言語では、変数がどこで宣言されたかによって、その変数を参照できる範囲(スコープ)が決まります。スコープの理解は、バグの防止や読みやすいコードを書くために非常に重要です。本記事では、グローバルスコープローカルスコープの基本ルールを、実行例とともにわかりやすく解説します。

グローバルスコープ(大域スコープ)とは

グローバルスコープとは、関数やブロックの外側で宣言された変数が適用されるスコープのことです。グローバル変数は、プログラムの先頭からプログラム終了まで、すべての関数から参照・操作することができます。

サンプルコード

#include <stdio.h>

int c = 30; /* グローバル領域で宣言 */

void fun(void);

int main(void) {
    int a = 10; /* ローカル変数 */
    printf("a=%d, c=%d\n", a, c);
    fun();
    return 0;
}

void fun(void) {
    printf("c=%d\n", c); /* グローバル変数cを参照 */
}

実行結果

a=10, c=30
c=30

この例では、変数cはグローバル領域で宣言されているため、main関数だけでなく、別の関数であるfunからも参照できています。

ローカルスコープ(局所スコープ)とは

ローカルスコープとは、ブロック({ }で囲まれた範囲)や関数の内側で宣言された変数が適用されるスコープのことです。ローカル変数は、そのブロック内でのみ有効であり、ブロックの外側からは参照できません。ブロックの実行が終わると、ローカル変数はメモリ上から消滅します。

サンプルコード

#include <stdio.h>

int main(void) {
    int i = 1; /* ローカルスコープ */
    printf("%d ", i);
    {
        int j = 2; /* ローカルスコープ */
        printf("%d\n", j);
    }
    return 0;
}

実行結果

1 2

同じ名前の変数を別々のブロックで宣言した場合

異なるブロック内であれば、同じ名前の変数をそれぞれ宣言しても問題ありません。名前が同じでも、それぞれ独立した別個の変数として扱われます。

サンプルコード

#include <stdio.h>

int main(void) {
    {
        int i = 1; /* 同じ名前の変数 */
        printf("%d ", i);
    }
    {
        int i = 2; /* 同じ名前の変数 */
        printf("%d\n", i);
    }
    return 0;
}

実行結果

1 2

内側のブロックで再宣言すると外側の変数は「隠れる」

外側のブロックで宣言された変数と同じ名前の変数を、内側のブロックで再宣言するとどうなるでしょうか。この場合、内側のブロックが実行されている間、内側の変数が外側の変数を覆い隠す(マスクする)動作になります。

サンプルコード

#include <stdio.h>

int main(void) {
    int i = 1;
    {
        int i = 2; /* 外側のiをマスクする */
        printf("%d\n", i);
    }
    return 0;
}

実行結果

2

このように、内側のブロック内では新しく宣言されたi = 2が優先され、出力は「2」となります。

ネストしたブロックから外側の変数へのアクセス

逆に、内側のブロックで同じ名前の変数が宣言されていなければ、外側のブロックで宣言された変数には、ネストした内側のブロックからも自由にアクセスできます。

サンプルコード

#include <stdio.h>

int main(void) {
    int i = 1;
    {
        int j = 2;
        printf("%d ", j);
        printf("%d\n", i); /* 外側の変数iを参照 */
    }
    return 0;
}

実行結果

2 1

まとめ

  • グローバルスコープ:関数の外で宣言された変数は、プログラム全体から参照可能。
  • ローカルスコープ:ブロック内で宣言された変数は、そのブロック内でのみ有効。
  • 異なるブロックなら、同じ名前の変数を宣言しても独立して扱われる。
  • 内側のブロックで同名の変数を宣言すると、外側の変数は一時的に隠される。
  • 内側のブロックからは、同名の変数がない限り外側の変数へアクセスできる。

スコープのルールを正しく理解することで、意図しない変数の上書きやバグを防ぎ、安全で保守性の高いC言語プログラムを書けるようになります。

  1. C言語のシフト演算とは?左シフト・右シフト・補数の基本をわかりやすく解説

    問題 C言語を使用して、ある数値に対する左シフト・右シフト・補数(ビット反転)を求める簡単なプログラムを作成するには、どのようにすればよいのでしょうか。 解決方法 左シフト(<<) 変数の値を1ビットだけ左へシフトすると、その値は2倍になります。「a × 2」を計算したのと同じ結果です。 例:a = 10 の場合、a << 1 = 20 右シフト(>>) 変数の値を1ビットだけ右へシフトすると、その値は元の半分になります。「a ÷ 2」の整数除算と同じ結果です。 例:a = 10 の場合、a >> 1 = 5 サンプルプログラム 以下は、シ

  2. C言語の式の評価とは?優先順位と結合規則をわかりやすく解説

    C言語における式の評価の基本C言語では、コンパイラが「優先順位(precedence)」と「結合規則(associativity)」という2つのルールに基づいて式を評価します。これらのルールを正しく理解することは、意図したとおりにプログラムを動作させるために非常に重要です。優先順位(Precedence)とは1つの式の中に異なる優先度を持つ演算子が含まれている場合、Cコンパイラは優先順位のルールに従って評価を行います。優先順位が高い演算子ほど先に処理されます。例えば、次のような式を考えてみましょう。この場合、「*」(乗算)は「-」(減算)や「=」(代入)よりも優先順位が高いため、「10 * 2