『Cプログラミング専門課程』目次第4章メモリ

4.5 静的記憶領域 (2)


サンプルプログラム

   1: /*  statauto.c  --  関数内の変数 static と auto  */
   2: 
   3: #include        
   4: 
   5: void    statictest( int i )
   6: {
   7:         static  int     s;
   8:                 int     v;
   9: 
  10:         if( i > 0 ) {
  11:                 v = s = i;
  12:         }
  13:         --v;
  14:         --s;
  15:         printf( "s=%d  v=%d\n", s, v );
  16: }
  17: 
  18: void accident( void )
  19: {
  20:         int     w;
  21: 
  22:         w = 12345678;
  23: }
  24: 
  25: main()
  26: {
  27:         statictest( 100 );
  28:         statictest( 0 );
  29:         statictest( 0 );
  30:         accident(); 
  31:         statictest( 0 );
  32:         statictest( 0 );
  33:         statictest( 0 );
  34: }

関数statictestは、関数内部のstatic変数と通常の変数(auto変数)の違い を調べるためのものです。パラメータが正のとき、ローカルな変数の s と v に値をセットします。それ以外では、パラメータの値に関係なく s と v をデ クリメント (-1) してからその値をプリントします。

mainから関数statictestを呼び出すのに、最初だけパラメータを100にして 呼び出し、次から5回はパラメータ0で呼び出しているので、プリントアウト は、99,98,97,96,95,94と減っていくはずですが、実行結果は次のようになり ました。

実行結果

s=99  v=99
s=98  v=98
s=97  v=97
s=96  v=12345677
s=95  v=12345676
s=94  v=12345675

static宣言されたローカル変数のsは期待通りの動きです。しかし、static 宣言していないローカル変数 v は、最初は 99,98 と順調に減少しましたが、 突然 12345677 になり、また次から1ずつ減ります。途中で関数 accident が 呼ばれ、事故ったようです。

実は変数v が最初順調に行っていたように見えていたのは単なる偶然です。 ローカル変数は、関数から抜けだすと同時にその変数に割り当てられていたメ モリはどうなるか一切保証されていません。もし、関数を抜けた後も値を保持 したければ、staticをつけます。そうすれば、関数からリターン後も値は決し て壊されず、再度その関数に飛び込めば、その変数の値を参照できます。

これをうまく使えば、カウンタなどが作成できます。ただし、万一staticを つけ忘れると、カウンタの内容が壊され、訳の分らない動き始めます。

*常識*
  • 関数中のstatic変数は、関数からリターン後も保持される。
  • 関数中の変数は、関数の実行終了時に破棄される。

⇒⇒⇒⇒次ページへ


Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング専門課程』目次第4章メモリ