Tips

C言語 記憶クラス指定子【基礎 第20回】

ずいぶん期間が空いてしまいましたが、C言語基礎の20回目です。
前回といってもえらい前ですが変数のスコープについて取り上げましたので、今回は変数の記憶場所を指定する記憶クラス指定子について取り上げます。
記憶クラス指定子は変数をどこに記憶するのかということを指定することができるものです。
記憶クラスの指定子として「static」「auto」「extern」「register」などがあり、今回はautoとstaticについて取り上げます。(registerは基礎編なので省略します。externは複数ファイルにまたがる際に使用するのでここでは省略します。

宣言方法

この記憶クラス指定子を使用して変数を宣言するには以下のように行います。
//
記憶指定子 データ型 変数名
//

auto指定子

auto記憶クラス指定子は、宣言した際にメモリ上に領域が確保されます。
そしてメモリ上からその領域が解放されるのは変数が宣言された関数の処理が終了したときとなります。
そのため関数が何度も呼び出されてもその都度、メモリが確保され解放される形となります。プログラム終了まで
無駄にメモリを確保し続けるということはありません。実際に確保される領域はスタックといわれる領域です。
auto指定子はこのように関数が存在する間ということになるのでローカル変数で使用されるものとなり
グローバル変数につけるものではありません。
この記憶クラス指定子ですが、関数内で何も指定子をつけずに変数を宣言すると自動的につけられます。
今までのサンプルコードで使用していたローカル変数はauto指定子のついた変数ということになります。

static指定子

この指定子をつけて変数を宣言した場合は宣言が行われた関数の処理が終了しても変数の領域がメモリ上から解放されません。
メモリ上に確保されるのはプログラムが実行された時点で、メモリ上から解放されるのはプログラムの終了時となります。関数が呼び出されるたびに確保され、関数が終了すると解放されるauto指定子のついた変数とは挙動がことなるので使用の際は気を付けておく必要があります。
このように関数内で宣言されているにも関わらずの関数の開始終了に連動せず変数の値を保持し続けるため、
static指定子を使用している関数を様々なところから呼び出した場合、呼び出すタイミングで値が変更している
可能性があります。そういったことも考慮する必要があります。

この指定子はローカル変数だけでなくグローバル変数にも使用できます。
グローバル変数でstaticを使用した場合は、その変数が宣言されているファイル内でのみ有効となります。
ファイル内の関数であれば、問題なく使用できますがその他のファイルからは使用できません。
付けていないグローバル変数は他のファイル内の関数から使用できます・
このような特徴を持つことから、1つのファイルしか使用していない環境では特に違いがありません。

static指定子を使用した場合、保存される領域はスタックではなくメモリの静的領域という部分になります。
ここには以前出てきたグローバル変数も格納されます。

コードでの確認

#include <stdio.h>

void func(void){
	static int i = 0;
	printf("iの値は%dです\n", i);
	i++;
}
int main(void){
	printf("1回目呼び出し\n");
	func();
	printf(“2回目呼び出し\n");
	func();

	return(0);
}

実行結果は以下のようになります。

1回目呼び出し
iの値は0です
2回目呼び出し
iの値は1です

ちなみに4行目のstaticをつけないで変数iを宣言し初期化すると以下のようになります。

1回目呼び出し
iの値は0です
2回目呼び出し
iの値は0です

処理自体は関数func内で宣言した変数iの値を表示させているだけです。
staticを付けた場合、func関数のiの値が関数を終了しても保持されるため初期値は0となり、
表示結果が0となっています。その後6行目のインクリメントで1となります。
関数を終了してもそのまま1が保持されるため呼び出しごとに値が変わります。
2回目の呼び出し時には一回目の呼び出しで1となっているため表示結果は1となります。
もし3回目の呼び出しを行った場合はやはり値が保持されているため、2と表示されます。

staticを使用しない場合は、関数終了後に変数iはメモリ上から解放されるため、2回目の呼び出し時は再び0から始まります。
よってfunc関数を何度呼び出して値を表示させても変化がありません。

実践力が身につくC言語講座 連載リンク

競技プログラミングをイメージしたライブラリ活用講座
競技プログラミング風-標準Cライブラリ入門 連載

アルゴリズムをマスターして技術力アップ!
実践アルゴリズム講座 連載

パズルゲームの解析をテーマにしたC++講座
ゲーム解析プログラミング 連載

Recent News

Recent Tips

Tag Search