※本記事は広告を含みます。
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 はメモリ配置や設計にも関わるため、
早めにしっかり理解しておくと役立ちます。
この記事が参考になった方へ
技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。
小さなご相談からでもお気軽にご連絡ください。









コメント