C11におけるグローバル変数とローカル変数について。
//グローバル変数の定義
int i1_g = 10; //グローバル変数
//プロトタイプ宣言
void fu1(double, int);
void fu2();
//実行
void main() {
double d1 = 123.41; //main関数のローカル変数
int i2 = 100; //同上
printf("main関数\n・global = %d\n", i1_g); //10
printf("・d1 = %f\n・i2 = %d\n\n", d1, i2); //123.41 & 100
fu1(3.1, 4);
fu2();
}
//fu1関数の宣言
void fu1(double d1, int i2) { //fu1関数の引数でありローカル変数
printf("fu1関数\n・global = %d\n", i1_g); //10
printf("・d1 = %f\n・i2 = %d\n\n", d1, i2); //3.1 & 4
}
//fu2関数の宣言
void fu2() {
double d1 = -4.1; //fu2関数のローカル変数
int i2 = 2; //同上
printf("fu2関数\n・global = %d\n", i1_g); //10
printf("・d1 = %f\n・i2 = %d\n\n", d1, i2); //-4.1 & 2
}
グローバル変数とは、関数の外で宣言した変数のことです。
ローカル変数とは、関数の中で宣言した変数、もっと厳密に言うとブレイス(波括弧)内で宣言した変数のことです。
グローバル変数のスコープは、そのCファイル内すべてです。
そのグローバル変数が宣言されたCファイル内であれば、どこからでもそのグローバル変数を参照することができます。
〇変数のスコープ
変数のスコープとは、ある変数が使える有効範囲のことです。
スコープ内であればその変数の値を参照することができますし、スコープ外からであればその変数は存在しないことになります。
同じスコープ内に同名の変数を宣言することはできません。
しかしスコープが違うのであれば、同じCファイル内に同名の変数を何個宣言してもまったく問題はありません。
閑話休題。
ローカル変数のスコープは、その変数を宣言したブレイス(波括弧)の中だけです。
もしその関数のブレイス内で宣言したのであればスコープはその関数内のすべてになります。
しかしもしその関数内のif文のブレイスの中で宣言したのであれば、その変数のスコープはそのif文の中だけとなります。
同じ関数内でもif文のブレイスの外ではその変数を参照することはできません。
〇グローバル変数の欠点
じゃあスコープとかめんどうくさいから「もう全部グローバル関数でいいじゃん」となるかというと、残念(?)ながらそうはなりません。
なぜかというと、グローバル関数はそのCファイルの実行中は常にオブジェクトとして存在し続けるので、メモリの容量を食うからです。
逆にローカル変数は、その範囲の処理が終われば消滅してその分のメモリが解放されます。
つまりローカル変数は、グローバル変数よりもエコな変数というわけですね。
あともう1つの理由は、セキュリティー面での問題です。
グローバル変数に代入された値は残り続けるので、もしそこにキャッシュカードの暗証番号やらマイナンバーやらを代入してしまうと、知識と悪意を兼ね備えた人たちから簡単にその情報を抜かれてしまう恐れがあります。
主にこのメモリとセキュリティーの2つの面から、グローバル変数を不必要にたくさん宣言することはまったく推奨されていません。
ローカル変数で対応できる部分は、できるだけローカル変数を使うことが推奨されているようです。
以上です。