第14回 変数の種類

このドキュメントは http://icrus.org/c_language_beginers_course/ 上にあります.

 変数にはいろいろな属性があります.1つはいままでやってきたintやcharやdoubleの型です.そして,これから説明する記憶クラスと通用範囲(スコープ)があります.いままで出てきた変数やポインタは全て内部変数です.

[文法14]

記憶クラスにはauto,register,static,externがあります.それぞれどこで宣言するかで働きと通用範囲が違います.それを以下の表にまとめます.

宣言場所 記憶クラスの指定子 記憶場所 寿命 通用範囲


関数の内部 ①auto(省略可) スタック 消滅 宣言されている関数内
②register レジスタまたは 消滅 宣言されている関数内
③static 静的領域 不変 宣言されている関数内
④extern 他で定義されている外部変数をこの関数ないで 使用できることを宣言する

関数の外部 なし 静的領域 不変 全モジュールの全領域
③static 静的領域 不変 宣言されているモジュール
の全域
④extern 他で定義されている外部変数をこの宣言以降の モジュールの全域で使用することを宣言する.

1.自動変数:auto


 C言語でもっとも一般的な変数です.関数の中で宣言され,そのブロック内でのみ有効です.他のブロックではアクセスできません.ブロックの始めでスタックに生成され,ブロックの終わりで消滅します.指定子autoは普通省略します.

2.レジスタ変数:register

 記憶領域をCPUのレジスタに割り当てる以外は自動変数と同じです.使用頻度の高い変数に割り当てると,スピードの向上がはかれます.コンパイラにより数に制限があります.

3.静的変数:static

 関数の中でで宣言された静的変数はその関数の中のみでアクセス可能です.関数の外で宣言された変数は,そのモジュールの中のみでアクセスできます.
これらの静的変数はプログラムの開始から終了まで同一の記憶領域に確保され,消滅することはありません.つまり関数への再入時に前の値が保存されています.

4.外部変数:extern

 関数の外で記憶クラス指定子をつけずに定義されたものが外部変数となります.外部変数は全ての関数および全てのモジュールから参照できます.外部変数が定義される以前にそれを使用したい場合,および他のモジュールでそれを使用したい場合にはextern宣言を行います.
 外部変数の「定義」と「宣言」の意味の違いは重要です.定義はその偏すのメモリ割り当てを行いますが,宣言はその辺巣を指定した型で勝することを宣言するだけで,メモリ割り当ては行いません.したがって定義はプログラム中で1度だけなのに対して,宣言は何度でも行えます.

[プログラム例14-1]


01: #include <stdio.h>
02: void func(void);
03: int  x;
04:
05: void main(void){
06:     int  i;
07:
08:     for( i=0; i<3; i++ ){
09:         x=i;
10:         func();
11      }
12:     getchar();
13: }
14:
15: void func(void){
16:     int    i=0;
17:     static int  j=0;
18:     printf( "x=%d i=%d j=%d\n", x, i, j );
19:     i += 10;
20:     j += 10;
21: }


03行目→外部変数xを定義しています.
06行目→内部変数の自動変数iを宣言しています.
08~11行→関数func()を3回呼び出します.
16行目→内部変数の自動変数iを宣言しています.
17行目→内部変数の静的変数jを宣言しています.

[結果14-1]

コンパイル・実行すると次のよう表示されます.
x=0 i=0 j=0
x=1 i=0 j=10
x=2 i=0 j=20
リターンキーを押すとプログラムは終了します.

 結果を見て下さい.変数xは,外部変数ですので関数内で宣言なしに使えます.main(),func()どちらの変数でも宣言なしに外部変数xを使用しています.そのため9行目のように代入が行え,18行目のように関数printf()渡すことができます.
 main関数内では外部変数xの値を更新しながら,関数func()を呼び出しています.呼び出されるごとに自動変数iは初期化されます.また,静的変数jはプログラムの実行のはじめに1回だけ初期化され,あとはその値を保持します.ですから結果を見ても,変数iの値はいつも0であるのに対し,変数jの値は呼び出されるごとに0,10,20と変化します.





このドキュメントは http://icrus.org/c_language_beginers_course/ 上にあります.

2017,1 ssatoh@ 足立工科大学 工学部 情報通信工学科