auto int hogehoge; extern int fugafuga; register int foo; static int bar;
記憶クラスは4種類あるが,この中でstaticはローカル変数とグローバル変数では, 動作が異なる.したがって,5種類の動作があると考える.それぞれの動作について,次 節以降に説明する.
auto int hogehoge;
自動変数は,それが宣言されている関数が呼び出されたときに記憶領域--メモリー--
が確保されて,関数での処理が終了したら廃棄される.例えば,リスト1のよう
に関数hoge()を3回呼び出すプログラムの動作を考える.関数hoge()の中の変
数aは自動変数である.ゆえに,関数hoge()が呼び出される毎に記憶領域
aが初期化されて作成され,その関数の動作が終了する毎に廃棄が実行される.
自動的に記憶領域の処理を行われるので,「自動変数(auto)」と呼ばれる.
   1 #include <stdio.h>
   2 
   3 int hoge(void);
   4 
   5 //===========================================================
   6 // メイン関数
   7 //===========================================================
   8 int main(void)
   9 {
  10   int i, foo;
  11 
  12   for(i=1; i<=3; i++){
  13     foo = hoge();
  14     printf("%d\tfoo=%d\n", i, foo);
  15   }
  16 
  17   return 0;
  18 }
  19 
  20 //===========================================================
  21 // 自動変数を使ったユーザー定義関数 hoge
  22 //===========================================================
  23 int hoge(void)
  24 {
  25   int a=0;              // 自動変数 auto int a=0 もOK
  26 
  27   a++;                  // a = a+1 と同じ
  28 
  29   return a;
  30 }
このプログラムの実行結果は,以下のようになる.図2に関数呼出と 変数aの変化を示す.関数hoge()内の自動変数aは関数が呼び出された時 に作成され,関数での処理が終わった時点で消滅する.したがって,以下の結果が得られ るのである.
1 foo=1 2 foo=1 3 foo=1
static int hogehoge;
グローバル変数でも,変数の値を保存することができる.しかし,グローバル変数は他の関数か らもアクセスできるので,思わぬことで値が変更されることがある.したがって,変数の 値を保存する必要があるが,他の関数がそれを使わない場合,静的変数を使う.
静的変数を使ったプログラムをリスト2に示す.このプログラムの25行
目のみ,リスト1と異なる.すなわち, 関数hoge()の変数aが
静的変数になっている.
   1 #include <stdio.h>
   2 
   3 int hoge(void);
   4 
   5 //===========================================================
   6 // メイン関数
   7 //===========================================================
   8 int main(void)
   9 {
  10   int i, foo;
  11 
  12   for(i=1; i<=3; i++){
  13     foo = hoge();
  14     printf("%d\tfoo=%d\n", i, foo);
  15   }
  16 
  17   return 0;
  18 }
  19 
  20 //===========================================================
  21 // 静的変数を使ったユーザー定義関数 hoge
  22 //===========================================================
  23 int hoge(void)
  24 {
  25   static int a=0;       // 静的変数
  26 
  27   a++;                  // a = a+1 と同じ
  28 
  29   return a;
  30 }
このプログラムの実行結果は,以下のようになる.図3に1回目関数呼出と 変数aの変化を示す.関数hoge()内の静的変数aはプログラム実行に先立っ て--メイン関数の実行よりも前に--静的変数aは作成され,初期化(a=0)が行 われる.そして,プログラムが動作している間,その変数は保存される.したがって,以下の結果が得られ るのである.
1 foo=1 2 foo=2 3 foo=3
   1 #include <stdio.h>
   2 
   3 extern int foo;       // どこかで宣言されているグローバル変数
   4 
   5 int hoge(void);       // プロトタイプ宣言
   6 
   7 //===========================================================
   8 // メイン関数
   9 //===========================================================
  10 int main(void)
  11 {
  12   int i;
  13 
  14   for(i=1; i<=3; i++){
  15     hoge();
  16     printf("%d\tfoo=%d\n", i, foo);
  17   }
  18 
  19   return 0;
  20 }
   1 #include <stdio.h>
   2 
   3 int foo=0;                 //   グローバルな自動変数
   4 
   5 //===========================================================
   6 // グローバルな自動変数の値を変えるユーザー定義関数 hoge
   7 //===========================================================
   8 void hoge(void)
   9 {
  10 
  11   foo++;                  // foo = foo+1 と同じ
  12 
  13 }
複数のソースファイルから,ひとつの実行ファイルを作成する場合,コンパイルは次のよ うにする.
![]()
gcc -o jikkou file1.c file2.c
関数hoge()中のaはfile1.cとfile2.cで使えるグローバル変数なので,次の実 行結果が得られることが理解できるであろう.
1 foo=1 2 foo=2 3 foo=3
これを解決するには,A君のfile1.cでは,
static int gvalue;
int gvalue; extern int gvalue;
グローバル変数を静的に宣言した例をリスト6の3行目に示す.
この変数fooとリスト5の3行目のfooは名前が同一で
も全く異なるものである.リストリスト5と
6からひとつの実行ファイルを作成しても,2つのfooが保
存する内容は別物である.
   1 #include <stdio.h>
   2 
   3 static int foo=5;       // 静的なグローバル変数
   4 
   5 int hoge(void);         // プロトタイプ宣言
   6 
   7 //===========================================================
   8 // メイン関数
   9 //===========================================================
  10 int main(void)
  11 {
  12   int i;
  13 
  14   for(i=1; i<=3; i++){
  15     hoge();
  16     printf("%d\tfoo=%d\n", i, foo);
  17   }
  18 
  19   return 0;
  20 }
   1 #include <stdio.h>
   2 
   3 static int foo=0;                 //   グローバルな静的変数
   4 
   5 //===========================================================
   6 // グローバルな自動変数の値を変えるユーザー定義関数 hoge
   7 //===========================================================
   8 void hoge(void)
   9 {
  10 
  11   foo++;                  // foo = foo+1 と同じ
  12 
  13 }
静的なグローバル変数が理解できたならば,次の実行結果は納得できるであろう.リスト 5の16行目のfooは,file1.cのグローバル変数のfoo のことである.
1 foo=5 2 foo=5 3 foo=5
register int rgsval;
一般に,アクセスの多い変数をレジスターに割り付ける.例えば,ループ文の制御変数で ある.リスト7の例では,制御変数のiとj,計算結果を格 納する変数kにレジスター変数を割り当てている.
   1 #include <stdio.h>
   2 
   3 //===========================================================
   4 // メイン関数
   5 //===========================================================
   6 int main(void)
   7 {
   8   register int i, j, k=0;
   9 
  10   for(i=1; i<=10000; i++){
  11     for(j=1; j<=10000; j++){
  12       k=i+j;
  13     }
  14   }
  15 
  16   return 0;
  17 }
次のようにすると,プログラムの実行時間が分かる.ただし,リスト 7をコンパイルした実行ファイルをtest_regとする.
![]()
time ./test_reg
実行結果は,次のようになる.最初のrealが実際にプログラムの実行に要した時間である.
real 0m0.110s user 0m0.108s sys 0m0.000s
レジスター変数を使わない場合,realの時間は0.227秒であった.レジスター変数を使う と倍の速度で計算できることが分かる.