Phase #08

変数の記憶クラス


1.記憶クラス

C言語ではデータを表現するものとして変数が使われます。ここまでの話の中で変数の型については説明しました。
この章では変数の「記憶クラス」という考え方を学びます。記憶クラスは変数がプログラム中のどの範囲で参照可能なのか、コンピュータのハードウェアにどのようにデータが保持されるか、という性質を表したものです。それぞれ通用範囲と記憶領域と呼びます。では、それぞれ見てみましょう。

2.通用範囲


定義された変数がプログラムのどの範囲で使うことが出来るかを示すのが通用範囲です。スコープともいいます。この通用範囲によって変数を分類すると「ローカル変数」と「グローバル変数」に分けられます。

ローカル変数
  ローカル(局所)な部分で使う変数。関数の中で定義され、その関数の中でのみ参照できる
グローバル変数
  グローバル(大域)な部分で使う変数。関数の外で定義され、どこからでも参照できる
ローカル変数とグローバル変数

[ 例 ] ローカル変数とグローバル変数の例  ex8-1.cGet! ソースファイル
/* --< グローバル変数 >-- */
int count;

/* ---< プロトタイプ宣言 >--- */
void print_max (int val1, int val2, int val3);

void main (void)
{
 count++; /* countはどこからでも参照できる */
 print_max (10,3,50);

 count++;
 print_max (23,6,17);
}

void print_max (int val1,int val2,int val3)
{
 int max; /* max は print_max()内だけで
        使えるローカル変数 */


 if (val1 > val2) {
  max = val1;
 } else {
  max = val2;
 }
 if (val3 > max) {
  max = val3;
 }

 /* countはどこからでも参照できる */
 printf ("count = %d max = %d\n", count, max);
}
count はグローバル変数なので、main ( ) でも print_max ( ) でも参照できます。一方、max は print_max ( ) 内でだけ使えるローカル変数なので、main ( ) 内では参照できません。

3.記憶領域


変数がコンピュータのハードウェア上にどのように確保されるかを示すのが記憶領域です。
この記憶領域は「静的領域」と「動的領域」に分けられます。

静的領域
  プログラムの実行中メモリ上の同じ場所に存在する記憶領域。
  確保される場所は「メモリ内のデータ領域(*)」。
動的領域
  静的領域とは逆でプログラムの実行中に確保されたり削除されたりする一時的な記憶領域。
  確保される場所は「メモリ内のスタック領域(*)」と「レジスタ(*)」。
領域の確保される場所

4.記憶クラスの宣言方法


記憶クラスの宣言は変数の宣言をするときにデータ型と同時に宣言をします。

 [記憶クラス] データ型 変数名 

今までの変数宣言は型宣言だけで記憶クラスの宣言を省略していたのです。このように記憶クラスの宣言は省略することもできます。
さて、宣言に使う記憶クラスは次の4通りです。

○自動変数 auto
○レジスタ変数 register
○外部変数参照 extern
○静的変数 static

それではそれぞれがどのような働きなのかを見てみましょう。

A.自動変数 auto


自動変数関数内部で宣言されその関数内でのみ有効な変数(=ローカル変数)です。確保される領域はスタック領域またはレジスタ上(=動的領域)です。
関数内の変数宣言時に記憶クラスを省略するとこの自動変数と見なされます。通常は auto は省略します。

通用範囲記憶領域
ローカル変数動的領域

int func (void)
{
 auto int sun;
 auto char buf [10] ;
 auto long size;
 ・・・
}
 = int func (void)
{
 int sun;
 char buf [10] ;
 long size;
 ・・・
}

B.レジスタ変数 register


レジスタ変数自動変数をレジスタに割り当てたい場合に使います。レジスタに変数を確保するとプログラムの実行速度が高められるので関数内で何度も使われる変数に用いると効果的です。
レジスタ変数に指定できるデータ型は限定されています。可能なデータ型は、char型int型、ポインタ(今後別の章で説明されます)です。

通用範囲記憶領域
ローカル変数動的領域

 register int sum ; /* int型の変数をレジスタ変数で宣言 */
 float avg ; /* float型はレジスタ変数に指定できない */

レジスタの数はとても少ないのレジスタ変数として宣言できる変数の数も制限されてしまいます。このレジスタの数を超えて宣言された場合は自動変数として扱われます。
レジスタはCPUの内部にあるのでCPUの特徴を十分理解しないと意味がありません。例えば、レジスタが4つしかないの一度に10個ものレジスタ変数を宣言しても意味がないと言うことです。
しかし、現在使われているほとんどのコンパイラは、プログラムの実行速度が速くなるように変数の割り当てを最適化してくれます。つまり、プログラマがレジスタ変数を意識して使う必要性はほとんどありません。
特別な理由があって最適化しない場合は、次のように宣言するとコンパイラは最適化処理は行いません。

volatile int dat;


Jump to Phase #07-3Phase #07-3: コンパイルの過程(3) へ
Phase #08-2: 変数の記憶クラス(2) へJump to Phase #08-2

△戻る
▲トップに戻る