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

C言語のストレージクラス徹底解説|auto・extern・static・registerの違い

C言語では、変数や関数の可視性(visibility)スコープ(scope)といった特性は、ストレージクラス(記憶クラス)によって定義されます。ストレージクラスを指定することで、その変数や関数がプログラムのどこからアクセス可能で、どの程度の期間メモリ上に存在し続けるのかが決まります。

C言語のストレージクラスには、以下の4種類があります。

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

auto(自動変数)

autoは、すべてのローカル変数に適用されるデフォルトのストレージクラスです。auto変数は関数が呼び出されたときに生成され、関数の実行が完了すると自動的に破棄されます。

関数ブロック内でのみ有効であることから「ローカル変数」とも呼ばれます。初期化しなかった場合、コンパイラによって不定値(ゴミ値)が割り当てられるため、使用する前に必ず明示的に初期化しましょう。

autoの特性

  • スコープ: 定義された関数ブロック内に限定される(ローカル)
  • デフォルト値: 不定値(ゴミ値)
  • 寿命: 定義されたブロックの実行期間に限定される

以下は、C言語におけるauto変数の使用例です。

サンプルコード

#include <stdio.h>
int main() {
    auto int a = 28;
    int b = 8;
    printf("The value of auto variable : %d\n", a);
    printf("The sum of auto variable & integer variable : %d", (a+b));
    return 0;
}

実行結果

The value of auto variable : 28
The sum of auto variable & integer variable : 36

なお、autoはローカル変数のデフォルト指定であるため、通常は明示的に記述する必要はありません。

extern(外部変数)

extern変数はグローバル変数とも呼ばれます。関数の外側で定義され、プログラム全体のどこからでもアクセスできます。また、関数からグローバル変数の値を書き換えることも可能です。

externの特性

  • スコープ: 特定の関数に束縛されず、プログラム全体(グローバル)で有効
  • デフォルト値: 0(ゼロ)
  • 寿命: プログラムの実行が終了するまで

以下は、C言語におけるextern変数の使用例です。

サンプルコード

#include <stdio.h>
extern int x = 32;
int b = 8;
int main() {
    auto int a = 28;
    extern int b;
    printf("The value of auto variable : %d\n", a);
    printf("The value of extern variables x and b : %d,%d\n",x,b);
    x = 15;
    printf("The value of modified extern variable x : %d\n",x);
    return 0;
}

実行結果

The value of auto variable : 28
The value of extern variables x and b : 32,8
The value of modified extern variable x : 15

このように、extern変数は関数内から値を変更(15に更新)でき、その変更はプログラム全体に反映されます。

static(静的変数)

static変数はプログラム実行中に一度だけ初期化され、その値はプログラムが終了するまで保持されます。static変数は関数の内側でも外側でも定義できます。

特に、関数内で定義したstatic変数は、関数が何度呼び出されても前回の値を記憶し続けるため、呼び出し回数のカウントや状態の保持などに便利です。

staticの特性

  • スコープ: 定義されたブロック内(ローカル)
  • デフォルト値: 0(ゼロ)
  • 寿命: プログラムの実行が終了するまで

以下は、C言語におけるstatic変数の使用例です。

サンプルコード

#include <stdio.h>
int main() {
    auto int a = -28;
    static int b = 8;
    printf("The value of auto variable : %d\n", a);
    printf("The value of static variable b : %d\n",b);
    if(a!=0)
    printf("The sum of static variable and auto variable : %d\n",(b+a));
    return 0;
}

実行結果

The value of auto variable : -28
The value of static variable b : 8
The sum of static variable and auto variable : -20

register(レジスタ変数)

register変数は、メモリではなくCPUのレジスタに格納するようコンパイラに指示します。頻繁にアクセスされる変数をレジスタに置くことで、高速な読み書きが可能になります。ただし、レジスタ変数はメモリ上に存在しないため、アドレスを取得することはできません(&演算子は使用不可)。

なお、registerはあくまでコンパイラへの「ヒント」であり、必ずしもレジスタに割り当てられるとは限りません。

registerの特性

  • スコープ: 関数内(ローカル)
  • デフォルト値: 不定値(ゴミ値)
  • 寿命: 定義されたブロックの実行が終了するまで

以下は、C言語におけるregister変数の使用例です。

サンプルコード

#include <stdio.h>
int main() {
    register char x = 'S';
    register int a = 10;
    auto int b = 8;
    printf("The value of register variable x : %c\n",x);
    printf("The sum of auto and register variable : %d",(a+b));
    return 0;
}

実行結果

The value of register variable x : S
The sum of auto and register variable : 18

4つのストレージクラス比較まとめ

ストレージクラススコープデフォルト値寿命
autoブロック内(ローカル)不定値ブロックの実行中
externプログラム全体(グローバル)0プログラム終了まで
staticブロック内(ローカル)0プログラム終了まで
register関数内(ローカル)不定値ブロックの実行中

用途に応じて適切なストレージクラスを選択することで、変数の意図しない書き換えを防ぎ、より安全で効率的なプログラムを書くことができます。特にグローバル変数(extern)の乱用はバグの原因になりやすいため、可能な限りローカル変数やstatic変数の活用を心がけましょう。

  1. JavaScriptでHTMLのH1要素のテキストを変数に取得する方法

    HTML内の <h1> 要素のテキストをJavaScriptの変数に格納したい場合は、document.getElementById() と innerHTML を組み合わせて使用するのが基本です。 H1の値を取得する基本的な方法 document.getElementById(id名).innerHTML と記述することで、指定したIDを持つ要素の内容(テキスト)を取得できます。 例として、次のようなH1見出しがHTMLにあると仮定しましょう。 <h1 id=demo>これはJavaScriptのデモプログラムです……</h1> このH1の値を取得するには

  2. HTML DOM ストレージの setItem() メソッドの使い方

    HTML DOM の Storage setItem() メソッドは、指定したキー名と値のペアをストレージオブジェクトに保存(追加・更新)するために使用されます。同じキー名がすでに存在する場合は、古い値が新しい値で上書きされます。データは永続的に保持される localStorage、またはブラウザセッション中のみ有効な sessionStorage のどちらにも保存できます。構文Storage setItem() メソッドの構文は以下のとおりです。localStorage.setItem(keyname, value);またはsessionStorage.setItem(keyname, va