トラック7・🧩関数とスコープ

グローバル変数との付き合い方

読む目安 約11分・ゴール:グローバル変数の性質と危険を理解し、使いどころを判断できる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

関数の外側、ファイルの先頭で宣言した変数は、そのファイルのどの関数からも見えます。これがグローバル変数です。家中の誰でも触れる、廊下に置かれた共有の棚だと思ってください。

#include <stdio.h>

int total = 0;        // グローバル変数(初期値を書かなければ0)

void add(int n)
{
    total += n;       // どこからでも触れる
}

int main(void)
{
    add(3);
    add(4);
    printf("%d\n", total);   // 7
    return 0;
}

引数も戻り値もなしに値を共有できるので、一見すると便利です。寿命はプログラムの開始から終了までで、初期値を書かなければ 0 に初期化されます(static 局所変数と同じ性質です)。

なぜ「便利」に見えるのか

グローバル変数を使えば、引数と戻り値をどう設計するか考えずに済みます。書くのが速い——これが最大の誘惑です。ところがプログラムが育つほど、「速く書ける」より「速く直せる」ほうが大切になります。バグの原因を探している時間は、コードを書いている時間よりずっと長いからです。

便利さの代償

しかしグローバル変数は、規模が大きくなるほど扱いにくくなります。

そこで、外に出したくないグローバルには static を付けます。

static int total = 0;   // このファイルの中だけから見える

局所変数に付ける static は「寿命を延ばす」意味でしたが、グローバルに付ける static は「見える範囲をこのファイルに限定する」という別の意味になります。同じキーワードで役割が2つある、Cの少しややこしい部分です。

局所変数で足りないか、まず疑う

グローバルにしたくなったら、次の順に検討してください。上から順に「見える範囲が狭い」順です。

  1. その関数の中だけで済む → 局所変数
  2. 呼び出し元とやりとりすれば済む → 引数と戻り値
  3. その関数だけが値を覚えていればよい → static 局所変数
  4. どうしても複数の関数で共有が必要 → ファイル内 static のグローバル

いちばん狭い選択肢で足りるなら、それが最善です。どうしてもグローバルを使うなら、total のような短い名前は避け、g_total のようにひと目でグローバルと分かる名前にしておくと事故が減ります。

使ってよい場面

設定値や定数のように、書き換えない共有データはグローバルでも安全です。その場合は const を付けて、書き換えを文法レベルで禁止しておきます。

const double TAX_RATE = 0.10;   // 誰も書き換えられない

読むだけの共有データなら、誰から見えても事故は起きません。危ないのは「みんなが書き換えられる」状態のほうだ、と覚えておくと判断しやすくなります。

まとめ: グローバル変数は「便利だが追跡しづらい」。まずは引数と戻り値でやりとりし、どうしても共有が必要なときだけ、static や const で範囲と権限を絞って使いましょう。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

グローバル変数の説明として誤っているものはどれですか。

  1. 初期値を書かなければ 0 で初期化される
  2. プログラムの終了まで生き続ける
  3. 同じファイル内のどの関数からも読み書きできる
  4. 関数の中で値を書き換えても、関数を抜けると元に戻る
答えを見る

正解:D(関数の中で値を書き換えても、関数を抜けると元に戻る)

グローバル変数は書き換えたら書き換わったままです。元に戻ることはありません。だからこそ「どこで書き換わったのか」を追いにくく、多用すると原因調査が難しくなります。

確認問題 2

関数の外(ファイルの先頭)で static int total = 0; と書きました。この static の意味は ____ です。

  1. この変数はこのファイルの中からだけ見える
  2. この変数は値が書き換えられなくなる
  3. この変数は関数を抜けると消える
  4. この変数は毎回0に初期化し直される
答えを見る

正解:A(この変数はこのファイルの中からだけ見える)

static は付ける場所で意味が変わります。関数の中に付ければ「寿命を延ばす」、関数の外に付ければ「見える範囲をこのファイルに限定する」です。書き換え禁止は const の役割です。

「関数とスコープ」の目次

  1. 関数とは——処理に名前を付ける
  2. 引数と戻り値
  3. プロトタイプ宣言
  4. 変数のスコープ——見える範囲
  5. 変数の寿命とstatic
  6. コールスタック——関数呼び出しの舞台裏
  7. 値渡しの本質
  8. グローバル変数との付き合い方
  9. 関数分割の設計センス
  10. 再帰の入口——自分を呼ぶ関数

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版