staticとは?C言語での意味をわかりやすく解説【ローカル・グローバルの違い】

目次

C言語文法解説シリーズ

本記事は「C言語文法解説シリーズ」の1つです。
C言語の文法を、組み込み開発の視点も交えて解説します。

C言語の static は、初心者がつまずきやすいキーワードの1つです。

理由は、static使う場所によって意味が少し変わるからです。

たとえば static は、

  • ローカル変数につける場合
  • グローバル変数につける場合
  • 関数につける場合

で役割が異なります。

ただし、まったく別物というわけではありません。
どれも「この変数や関数をどう扱うか」を決めるためのものです。

この記事では、static の意味と使い方を、C言語の基本から組み込みでの見方まで整理して解説します。

初心者さん

staticって、結局何が変わるんですか?

エンジニアくん

使う場所によって変わるけど、まずは「値が残ることがある」「外から見えなくできることがある」と考えるといいよ

初心者さん

1つの意味じゃないんですね

エンジニアくん

そうなんだ。だから、ローカル変数・グローバル変数・関数に分けて見ると分かりやすいよ


staticとは?

static は、変数や関数の
「いつまで存在するか(寿命)」と
「どこから使えるか(公開範囲)」
に関係するキーワードです。

ただし、使う場所によって働きが変わります。

  • ローカル変数につける
    → 関数を抜けても値が残る
  • グローバル変数につける
    → そのファイル内だけで使える
  • 関数につける
    → そのファイル内だけで使える

この違いが、static を分かりにくく感じる原因です。

staticローカル変数

まず、普通のローカル変数を見てみます。

void func(void)
{
    int count = 0;
    count++;
    printf("%d\n", count);
}

この関数を何回呼んでも、表示は毎回 1 になります。

これは、count関数を呼ぶたびに作られ、関数を抜けると消えるからです。

では、static を付けるとどうなるでしょうか。

void func(void)
{
    static int count = 0;
    count++;
    printf("%d\n", count);
}

この場合は、関数を呼ぶたびに

1
2
3

のように増えていきます。

なぜ値が残るのか

static を付けたローカル変数は、見える範囲は関数内のままですが、
関数が終わっても消えません

つまり、

  • 使える場所はその関数の中だけ
  • でも値は次回呼び出しまで残る

という特徴を持ちます。

どんなときに使う?

たとえば、

  • 関数が何回呼ばれたか数えたい
  • 前回の値を覚えておきたい
  • その関数専用の状態を持たせたい

といった場面で使われます。

例:

int get_id(void)
{
    static int id = 0;
    return id++;
}

このようにすると、呼び出すたびに連番を返せます。

メモリ配置との関係

普通のローカル変数は stack に置かれますが、
static ローカル変数は data領域やbss領域 に置かれます。

そのため、関数を抜けても値が消えません。

static変数とメモリ配置の関連についてはこちらの記事で解説しています。

データ領域とBSS領域についてはこちらの記事で解説しています。

staticグローバル変数

次に、グローバル変数に static を付ける場合です。

static int g_value = 10;

この変数はグローバル変数なので、関数の外で定義されています。
ただし、static を付けることで、同じファイル内からしか使えなくなります

staticを付けないグローバル変数との違い

static を付けないグローバル変数は、他のファイルから extern を使って参照できます。

一方、static を付けると、そのファイルの外には公開されません。

つまり static グローバル変数は、

  • グローバルに存在する
  • でも外部ファイルには見せない

という変数です。

なぜ使う?

このファイルの中だけで使う内部状態を、外から勝手に触られないようにするためです。

たとえば、モジュール内部のカウンタや状態変数などに向いています。

static int error_count = 0;

こうしておけば、他のファイルから不用意に書き換えられません。

static変数とグローバル変数の使い分け

値を保持したい場合、次の2つの方法があります。

① staticローカル変数
② グローバル変数

例えば呼び出し回数を数える場合

staticローカル変数

void func(void)
{
    static int count = 0;
    count++;
}

グローバル変数

int count = 0;
void func(void)
{
    count++;
}

どちらも同じ動作になります。

では、どちらを使うべきでしょうか。

公開範囲は狭い方がいい

初心者さん

これってグローバル変数でもよくないですか?

エンジニアくん

動作は同じだけど、あまりおすすめしないかな

初心者さん

なんでですか?

エンジニアくん

グローバル変数はどこからでも変更できるからだよ

初心者さん

それって問題なんですか?

エンジニアくん

例えば別の関数が値を変えると、
どこで変更されたか分かりにくくなるんだ

初心者さん

ああ、バグの原因になりそうですね

エンジニアくん

そう。だから変数は
必要な範囲だけで使えるようにするのが基本なんだ

変数の公開範囲が広いほど、
意図しない場所から変更される可能性が増えます。

その結果

・バグの原因になる
・影響範囲が広がる
・コードの理解が難しくなる

といった問題が起こります。

そのため、変数は
必要な範囲だけで使えるようにする
のが基本です。

static を使うと、
公開範囲を制限できます。

この考え方については、次の記事で詳しく解説します。

👉 C言語でグローバル変数を避ける理由とは?staticを使った設計の基本

使い分けの考え方

staticローカル変数を使う

・その関数だけで使う
・状態を保持したい
・外部から触らせたくない

int get_id(void)
{
    static int id = 0;
    return id++;
}

グローバル変数を使う

・複数の関数で共有する
・システム状態として管理する

int system_mode;
void set_mode(int mode)
{
    system_mode = mode;
}

グローバル変数をより安全にするならstaticグローバル

static int system_mode;

これなら ・ファイル内共有 ・外部非公開 になります。

使い分けまとめ(重要)

staticローカル変数
→ 関数専用の状態

staticグローバル変数
→ ファイル専用の状態

グローバル変数
→ 全体共有の状態

この3段階で使い分けます。

グローバル変数のexternを使った公開についてはこちらの記事で解説しています。


static関数

関数にも static を付けられます。

static void calc_checksum(void)
{
    /* 内部処理 */
}

この場合、この関数は定義したファイルの中だけで使える関数になります。

他のファイルから呼び出すことはできません。

なぜ使う?

外部に公開する必要のない補助関数を、内部専用にするためです。

たとえば、

  • モジュール内部だけで使う計算関数
  • 分割のために作った補助関数
  • 他ファイルから呼ばせたくない関数

に使われます。

例:

static int calc_checksum(const unsigned char *data, int len)
{
    int sum = 0;
    for (int i = 0; i < len; i++)
    {
        sum += data[i];
    }
    return sum;
}

この関数は、そのファイルの内部実装として閉じておけます。


staticの意味を整理すると

ここまでの内容を整理すると、static は次のように使われます。

ローカル変数につけた場合

関数を抜けても値を保持するために使う

グローバル変数につけた場合

そのファイル内だけで使えるようにする

関数につけた場合

そのファイル内だけで使えるようにする

つまり static には、

  • 値を長く保持する
  • 外部に公開しない

という2つの見方があります。

どちらになるかは、付ける場所で決まります。


組み込み開発でstaticが重要な理由

組み込み開発では、static は特に重要です。

理由は、変数の寿命や配置場所を意識する場面が多いからです。

たとえば static ローカル変数は stack ではなく静的領域に置かれるため、
メモリ使用の考え方にも関わります。

また、static 関数や static グローバル変数を使うことで、
モジュールの内部実装を外に漏らさず、構造を整理しやすくなります。

つまり組み込みでは static は、単なる文法ではなく、

  • メモリの使い方
  • モジュール分割
  • 見せる範囲の制御

に関わる大事なキーワードです。

メモリ領域についてはこちらの記事で解説しています。


まとめ

static は、使う場所によって意味が変わるキーワードです。

  • static ローカル変数
    → 関数を抜けても値が残る
  • static グローバル変数
    → そのファイル内だけで使える
  • static 関数
    → そのファイル内だけで使える

特に組み込み開発では、static はメモリ配置や設計にも関わるため、
早めにしっかり理解しておくと役立ちます。

この記事が参考になった方へ

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

お問い合わせはこちら

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする


目次