ほぷしぃ

納得C言語!

[第9回]変数のスコープ

変数のスコープ


1.変数のスコープとは

スコープ(scope)とは日本語にすると"有効範囲"を表します。
つまり、変数のスコープは変数が使える有効範囲のことを指します。
有効範囲とは{ }で囲まれた部分の事です。


2.ローカル変数

今まで、main関数や自作関数の内側で変数を宣言行ってきましたね。
main関数内や自作関数内で宣言した変数のことをローカル変数と呼びます。
ローカル変数の有効範囲は変数を宣言した関数内のみとなります。
宣言した関数の有効範囲を超えて、他の関数で変数を使うことができませんので注意してください。


3.グローバル変数

実は、変数は関数の内側だけではなく関数の外側でも変数の宣言は出来ます。 関数の外側で宣言された変数のことをグローバル変数と呼びます。 ローカル変数の有効範囲は関数内のみで関数外からは使うことができませんでしたが、グローバル変数の有効範囲はプログラム全体となっているので、どの関数からもグローバル変数を呼び出すことができます。 これがローカル変数とグローバル変数の大きな違いです。

A「ローカル変数とグローバル変数ってどう違うの?」
B「ローカル変数は、それぞれの関数内で使うことしか出来ないんだ。それに対してグローバル変数はどの関数からでも使うことが出来るよ」
A「どうやれば使うようになるの?」
B「今までmain関数内で行ってきた変数の宣言をmain関数の{ }の外側で行えばいいよ」
A「外側ならどこでもいいの?」
B「前にも話したように、C言語は上から処理されるから、最初に宣言しよう」
A「分かった!」

さらに、グローバル変数はプログラムの開始処理の前に一度だけ初期化を行います。
明示的に初期化を行わないときは自動的に0になりますが、分かりやすくしておくためにグローバル変数でも明示的に初期化する値を与えておきましょう。

例題 ローカル変数とグローバル変数の違い

例題1 ローカル変数 例題2 グローバル変数
#include <stdio.h>

int main()
{
    //ローカル変数の宣言
    int a = 8;
    printf("a = %d\n",a);
    return 0;
}
#include <stdio.h>
//グローバル変数の宣言
int a = 8;

int main()
{
    printf("a = %d\n",a);
    return 0;
}
ローカル変数 グローバル変数

同じ結果になりましたね。
でも、やっていることは微妙に違います。

変数のスコープの範囲を図で表してみます。
スコープ範囲

赤色で囲った部分がグローバル変数の有効範囲です。
青色で囲った部分がローカル変数の有効範囲です。


4.静的ローカル変数

関数内のローカル変数は、関数が呼ばれる度に宣言されます。
変数の値は保持したいけど、グローバル変数にしたくないとき、関数が呼ばれる度に値が戻っちゃうのはとても嫌ですよね。
そこで、一度宣言したローカル変数の値を維持する方法を使います。
その方法とは・・・静的ローカル変数で変数を宣言することです。
宣言方法は簡単で、変数の型(int, double,...etc)の前に「static」を付けるだけです。
こうすることによって、プログラム中に複数回同じ関数が呼ばれても常に変数の値を維持することができます。
静的ローカル変数で宣言した変数はグローバル変数と同じようにプログラムの開始処理前に一度だけ初期化を行います。
明示的に初期化を行わないときはグローバル変数の同様、自動的に0になりますが、分かりやすくしておくためにグローバル変数でも明示的に初期化する値を与えておきましょう。

例題3 静的ローカル変数

#include <stdio.h> // おまじない

void count(void);
void count2(void);

int main()
{
    int i = 0;// 変数の宣言

    while(i<5){
        //自作関数の呼び出し
        count();
        count2();
        //見やすくするために改行
        printf("\n");
        i++;
    }
    return 0;
}

void count(void)
{
    //static有り=>関数を呼び出してもそのまま
    //     =>関数が最初に呼び出されたとき初期化
    static int count=3;
    //countの中身は記憶され続ける
    count++;
    printf("static有り=%d\n",count);
    return;
}

void count2(void)
{
    //static無し=>関数を呼び出すたびに初期化される
    int count=3;

    count++;
    printf("static無し=%d\n",count);
    return;
}

結果

静的ローカル変数

count関数は最初に呼び出されたときだけcount=3で初期化し、count++でcount=4となります。
次にcount関数が呼ばれたときは、count=4の値を保持しているのでcount++でcount=5となります。
count2はstatic宣言がされていないので、関数が呼び出されるたびにcount=3で初期化されてしまいますね。

[第8回]演習問題U ページのトップ [第10回]配列