C言語 変数の種類(記憶クラス)

C言語

記憶クラス

記憶クラスとは、変数が保存される場所を定義するもので、これにより、変数の使用範囲が決まります。

ここでは、C言語の記憶クラスとして自動変数、レジスタ変数、外部変数、静的変数についてみていきます。

自動変数

自動変数(auto変数)は、局所変数(ローカル変数)とも呼ばれます。この変数は、関数内部でのみ存在する変数です。関数呼び出しでRAMのスタック領域に領域が確保され、関数の終了とともに消滅します。

C言語では、関数内でautoを付けて宣言した変数は、自動変数として扱われます。

auto は省略が可能なので、単純に関数内で宣言した変数は、自動変数となります。

以下の変数aは、何れも自動変数となります。

main()
{
  int a = 123;
}
main()
{
  auto int a = 123;
}

レジスタ変数

レジスタ変数は、CPU内部の記憶領域であるレジスタに割り当てられる変数です。

自動変数と関数の引数にのみ適用可能な変数になります。

CPU内部の記憶領域のため、高速に処理することができます。

レジスタの数が限定されるので、レジスタ変数は、一度に多くは使えません。

組み込みプログラムになりますが、例えば、Renesas H8SX/1658MのCPU内部レジスタは、8個で、そのうち1つはスタックポインタ用となりますので、7個のレジスタしか使えないとなります。

プログラムでレジスタ数を超過してレジスタ変数を宣言した場合は、コンパイラに無視されるので、その場合でも誤動作を引き起こすような影響はありません。

レジスタ変数の宣言は、変数の型の前にregisterという文言を記述します。

main()
{
  register int a;
}

外部変数

外部変数は、関数の外部で定義する変数で、グローバル変数ともいいます。

外部変数として使用する変数は、別々の関数で共通の変数として扱われます。

異なるファイルで外部変数を使用する場合は、externという文言を記述して、使用します。一般的に、同一ファイルでの外部変数は、externを省略可能なので、同一ファイル内での外部変数には、externを付けません。

外部参照は、関数にも適用できます。外部変数同様にexternを付けることで外部関数として使用することができます。

プログラムの品質上、外部変数を多用することは、望ましくないので、ファイル間のデータのやり取りは、最低限の外部変数で構成できるようにプログラム設計を行うのがよいかと思います。

//同一ファイル内の外部変数a

void func(void);
int a=0;
main()
{
  fun();
  printf(“%d\n”,a);
}
void func(void)
{
  a++;
}
//異なるファイルでの外部変数a

//ファイル1
extern void func(void);
int a=0;
main()
{
  fun();
  printf(“%d\n”,a);
}

//----------------------------------
//ファイル2
extern int a;
void func(void)
{
  a++;
}

静的変数

静的変数は、変数の型の前にstaticという文言を記述して宣言する変数です。

静的変数は、宣言をしたファイル内で有効となります。

関数内で宣言した局所変数に対してもstatic宣言は可能で、その場合は、その関数内で永続的に使用できる変数となります。変数の初期値は、関数の初回実行時に一度だけ代入され、変数値は、プログラム実行中、保持され続けます。

自動変数の場合は、スタック領域に変数の領域が確保されていましたが、静的変数の場合は、コンパイル時に固定メモリ上に領域が確保されます。これにより、プログラム実行中も変数のメモリ領域が消滅することなく、存在し続けることができるとなります。

外部変数にstatic宣言を付けた場合、その変数は、宣言したファイル内で使用可能な変数となります。この変数は、外部ファイルから変更されることがありません。また、外部ファイルと同一の変数名があっても異なる変数として扱われます。

外部に公開する必要のない変数は、なるべく静的変数として定義しておいたほうがプログラム品質的にもよいと考えます。

変数のstatic宣言と同様に関数もstatic宣言することができます。staticな関数は、宣言したファイル内で有効な関数として定義されます。

#include <stdio.h>
static void func(void);
static int x = 0;

main()
{
    int i;
    for(i=0;i<5;i++){
        func();
        printf("x=%d\n",x);
    }
    printf("end\n");
}

static void func(void)
{
    static int a = 0;
    auto int b = 0;
    printf("a=%d b=%d\n",a,b);
    a++;
    b++;
    x++;
}
C:\prog>static_test
a=0 b=0
x=1
a=1 b=0
x=2
a=2 b=0
x=3
a=3 b=0
x=4
a=4 b=0
x=5
end

コメント

タイトルとURLをコピーしました