Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語のストレージクラス徹底解説|auto・extern・static・registerの違いとサンプルコード

C言語には、変数や関数の「有効範囲(スコープ)」と「寿命」を決めるストレージクラスが用意されています。ストレージクラスを正しく理解することで、メモリの使い方やプログラムの動作をより細かく制御できるようになります。

ストレージクラスとは?

ストレージクラスとは、Cプログラム内で宣言された変数や関数のスコープ(有効範囲)寿命(生存期間)を定義する概念です。これにより、その変数がどこからアクセス可能で、いつまで値を保持するのかが決まります。

C言語の4つのストレージクラス

C言語で使用できるストレージクラスは以下の4種類です。

  • auto(自動変数)
  • extern(外部変数)
  • static(静的変数)
  • register(レジスタ変数)

それぞれの特徴を、サンプルプログラムと実行結果とともに詳しく見ていきましょう。


1. 自動変数(auto)/ローカル変数

  • キーワード:auto
  • 別名:ローカル変数とも呼ばれます
  • スコープ:宣言されたブロック({ } の中)でのみ有効です
  • 宣言場所:ブロックの内部で宣言します
  • デフォルト値:不定値(ガベージ値)

auto変数は、宣言されたブロックを抜けると自動的に破棄されます。初期化しない場合、値は不定となるため注意が必要です。

サンプルプログラム

#include<stdio.h>
void main (){
    auto int i=1;{
        auto int i=2;{
            auto int i=3;
            printf ("%d",i);
        }
        printf("%d", i);
    }
    printf("%d", i);
}

実行結果

3 2 1

このプログラムでは、同じ名前「i」がネストした各ブロック内で個別に宣言されています。それぞれのブロック内では、そのブロックで宣言された変数が優先されるため、「3 → 2 → 1」の順に出力されます。


2. 外部変数(extern)/グローバル変数

  • キーワード:extern
  • 別名:グローバル変数とも呼ばれます
  • スコープ:プログラム全体で有効です
  • 宣言場所:ブロックの外部で宣言します
  • デフォルト値:0(ゼロ)

extern変数はすべての関数からアクセスでき、プログラムが終了するまで値を保持し続けます。

サンプルプログラム

#include<stdio.h>
extern int i =1; /* このiはプログラム全体で有効 */
main (){
    int i = 3; /* このiはmain関数内でのみ有効 */
    printf ("%d", i);
    fun ();
}
fun (){
    printf ("%d", i);
}

実行結果

31

main関数内で宣言されたローカル変数「i = 3」が優先されて出力され、続いてfun関数ではグローバル変数「i = 1」が出力されるため、結果は「31」となります。


3. 静的変数(static)

  • キーワード:static
  • スコープ:プログラム全体を通じて値を保持し、関数呼び出しの間も値が維持されます
  • 初期化:初期化は一度だけ行われます
  • デフォルト値:0(ゼロ)

static変数は、関数が何度呼び出されても前回の値を記憶しています。カウンタなど、呼び出し回数を追跡したい場面で特に便利です。

サンプルプログラム

#include<stdio.h>
main (){
    inc ();
    inc ();
    inc ();
}
inc (){
    static int i =1;
    printf ("%d", i);
    i++;
}

実行結果

1     2     3

inc関数を3回呼び出していますが、static変数「i」は初期化が一度しか行われず、値が保持されるため「1 → 2 → 3」と増加していきます。


4. レジスタ変数(register)

  • キーワード:register
  • 特徴:通常の変数が格納されるメモリではなく、CPUのレジスタに値が保存されます
  • レジスタとは:CPU内部にある一時的な記憶領域のことです

レジスタはメモリよりも高速にアクセスできるため、ループカウンタなど頻繁にアクセスする変数に指定すると処理速度の向上が期待できます。ただし、レジスタの数には限りがあるため、必ずしもレジスタに割り当てられるとは限りません。

サンプルプログラム

#include<stdio.h>
main (){
    register int i;
    for (i=1; i<=5; i++)
        printf ("%d",i);
}

実行結果

1 2 3 4 5

まとめ:ストレージクラス比較表

ストレージクラスキーワードスコープデフォルト値
自動変数auto宣言されたブロック内のみ不定値(ガベージ値)
外部変数externプログラム全体0
静的変数staticプログラム終了まで値を保持0
レジスタ変数register宣言されたブロック内のみ不定値(ガベージ値)

用途に応じて適切なストレージクラスを選択することで、効率的でバグの少ないCプログラムを書くことができます。特にstaticによる値の保持や、externによるグローバルなデータ共有は、実際の開発でも頻繁に活用される重要なテクニックです。

  1. C言語の演算子と式の種類を徹底解説!算術からビット演算まで

    C言語における演算子(オペレーター)とは、データに対して何らかの操作を行うための記号です。C言語の演算子は、その機能によって以下のように分類されます。算術演算子関係演算子論理演算子代入演算子インクリメント・デクリメント演算子ビット演算子条件演算子特殊演算子それぞれの演算子について、具体例とサンプルプログラムを交えながら詳しく見ていきましょう。1. 算術演算子算術演算子は、足し算や引き算などの数値計算を行うために使われます。演算子説明例a=20, b=10 の場合結果+加算(足し算)a+b20+1030-減算(引き算)a-b20-1010*乗算(掛け算)a*b20*10200/除算(割り算)a/

  2. C言語の探索アルゴリズム解説|線形探索と二分探索の違いと実装例

    探索(サーチ)とは、複数の要素で構成されるリストの中から、目的の「キー」となる要素を見つけ出す処理のことです。 リストの中に指定した要素が存在すれば、その探索は「成功」とみなされます。 指定した要素がリストに存在しなければ、その探索は「失敗(不成功)」となります。 C言語で広く使われている代表的な探索手法は、主に次の2つです。 線形探索(Linear Search/リニアサーチ) 二分探索(Binary Search/バイナリサーチ) 線形探索(Linear Search)とは 線形探索は、リストの先頭から順に要素を1つずつ取り出し、キーと一致するかどうかを確認していく、最も基本的な探