
C言語入門|危険と隣り合わせのグローバル変数
引数や戻り値のルールを学んでいると、こんな気持ちになることがあります。
「引数とか戻り値とか、正直ちょっと面倒じゃないですか?」
「main 関数で用意した変数を、どこからでも使えたら楽なのに……」
うん、その感覚、とても自然です。
実はC言語には、その願いを叶える仕組み がちゃんと用意されています。
それが グローバル変数 です。
ただし、この仕組みは
便利さと引き換えに、かなり危険な性質 も持っています。

グローバル変数とは何か
これまで変数は、main 関数や add 関数など、
関数の中 で宣言してきました。
ところがC言語では、
すべての関数の外 に変数を宣言することができます。
プロジェクト名:8-13-1 ソースファイル名: sample8-13-1.c
#include <stdio.h>
int baseValue = 100; // グローバル変数
void showValue(void)
{
printf("現在の値は %d です\n", baseValue);
}
int main(void)
{
baseValue = 150;
showValue();
return 0;
}このように宣言された変数を グローバル変数 と呼びます。
特徴をまとめると、次のようになります。
| 項目 | 内容 |
|---|---|
| 宣言場所 | 関数の外 |
| 有効範囲 | 宣言された行以降のすべての関数 |
| アクセス | どの関数からも読み書き可能 |
「おお、全部の関数から使える!便利!」
……そう思いますよね。
でも、ここで一度立ち止まりましょう。
便利さの裏に潜むデメリット
「すべての関数で同じ変数を使える」
これは一見すると、とても魅力的です。
しかし、この性質には次のような 大きな欠点 があります。
| 問題点 | 内容 |
|---|---|
| 名前の衝突 | 別の場所で同名変数を宣言できない。 |
| 予期せぬ変更 | どの関数でも値を書き換えられてしまう。 |
| デバッグ困難 | どこで値が変わったのか追いにくい。 |
関数が3つや4つ程度なら、まだ把握できるかもしれません。
ですが、関数が増えてくると状況は一変します。
「この値、いつ変わったんだ?」
「え、ここで書き換えられてるの?」
こうした問題が積み重なり、
グローバル変数が致命的な不具合の原因になる ことは、
昔からよく知られています。
なぜグローバル変数は嫌われがちなのか
実務の現場では、
- グローバル変数は原則禁止
- 使用する場合は厳格なルール付き
というプロジェクトも珍しくありません。
中には、
- グローバル変数を使えない言語
- 使うと警告が出る言語
も存在します。
それほどまでに、
グローバル変数は扱いが難しい存在 なのです。
とはいえ、完全な悪者というわけではありません。
グローバル変数に頼る前に考えること
グローバル変数を使いたくなったら、
まず次の問いを自分に投げかけてみてください。
引数と戻り値で解決できないだろうか?
多くの場合、
引数と戻り値を使えば、きれいに解決できます。
グローバル変数は、
「どうしてもそれしか方法がないときの最終手段」
くらいに考えておくのが安全です。
変数以外にも存在するグローバルな宣言
関数の外で宣言できるのは、変数だけではありません。
次のような定義も、
関数の外に記述することができます。
| 宣言できるもの | 例 |
|---|---|
| 列挙体 | enum |
| 構造体型 | struct |
| 型定義 | typedef |
enum Element { FIRE, WATER, WIND, EARTH };
int main(void)
{
printf("%d\n", FIRE);
return 0;
}このように定義すると、
FIRE や WIND をすべての関数で安全に利用できます。
これは 問題の少ないグローバル利用 の代表例です。
名前の重複と隠蔽に注意
C言語では、
ブロックの内外で同じ名前の変数を宣言すること ができます。
int age = 4; // グローバル変数
int main(void)
{
int age = 39; // ローカル変数
printf("%d\n", age); // 39 が表示される
return 0;
}この場合、main 関数の中では
ローカル変数 age が優先 され、
グローバル変数 age は隠蔽されます。
この挙動を理解していないと、
思わぬ不具合につながることがあります。
安全に書くためのコーディング指針
グローバル変数を使う場合は、
次のようなルールを意識すると安全性が高まります。
| ルール | 内容 |
|---|---|
| ① | グローバル変数を乱用しない。 |
| ② | 変数名の先頭に g_ などの接頭辞を付ける。 |
| ③ | ブロックのネストを深くしすぎない。 |
| ④ | ループ変数以外で i や j を多用しない。 |
これだけでも、
トラブルの多くは防げます。
まとめ:便利だが常に危険と隣り合わせ
グローバル変数は、
- 書くのは楽
- 使うのも楽
その一方で、
- 壊すのは一瞬
- 直すのは大変
という性質を持っています。
まずは 引数と戻り値で設計する。
それでもどうしても必要なときに、
リスクを理解したうえで使う。
これが、C言語と長く付き合うためのコツです。
