Thinkers'Studio
JavaとC言語の自習ツール
C言語における変数の初期化についての整理

 関数内で宣言した変数は、初期化せずに参照すると不定値が入っています。
 関数の外で定義した変数は明示的に初期化しなくても、自動的に 0 で初期化されます。
 今回は、そのような変数の初期化に関することを少し整理したいと思います。

ここで取り上げる変数の区別

宣言場所の違い

 ローカル変数 (宣言した関数または宣言したブロック内だけで使用可能)
 グローバル変数 (関数外で定義、定義以降どの関数からでも使用できる)

ローカル変数内の記憶クラスの違い

 自動変数 (関数やブロックなど宣言された範囲以外では消えてしまう)、auto をつけて宣言するがふつう省略される
 静的変数 (プログラム実行中は値を保持する。関数やブロックで定義した場合その中だけで有効)、static をつけて宣言する

グローバル変数で static をつけるとスコープの制限

 グローバル変数はすべて静的で、プログラム実行中存在します。 グローバル変数にも static をつけて宣言することができますが、それはスコープ(有効範囲)をそのファイル内に限定するという指示です。

【 いろいろな変数宣言 】
 明示的に初期化しなかった場合の値を、変数定義の右にコメントで書いています。
 プログラムの下で、整理します。

#include <stdio.h>

//グローバル変数        //初期化しないと
int  gn;                //0
int  gnarray[5];        //0, 0, 0, 0, 0
char gstr[12];          //空文字列

//スコープを制限したグローバル変数
                        //初期化しないと
static int sgn;         //0
static int sgnarray[5]; //0, 0, 0, 0, 0
static char sgstr[12];  //空文字列

main()
{
    //ローカルな自動変数        //初期化しないと
    int n;                      //不定値
    int narray1[5];             //不定値
    char str[12];               //不定値
                                //配列の一部を初期化
    int narray2[5] = { 2, 1 };  //2, 1, 0, 0, 0

    //ローカルな静的変数        //初期化しないと
    static int sn;              //0
    static int snarray[5];      //0, 0, 0, 0, 0
    static char sstr[12];       //空文字列
}

初期化の違い

1. 関数内で定義されるローカル変数

 明示的に初期化するとき ・・・ その関数またはそのブロックが実行されるたびにその値で初期化される
 明示的に初期化しないとき ・・・ 不定値が入っている

2. 関数の外で定義されるグローバル変数

 明示的に初期化するとき ・・・ プログラム実行時に1度だけその値で初期化される
 明示的に初期化しないとき ・・・ 自動的に 0 で初期化される

3. ローカル変数に static をつけた静的変数

 明示的に初期化するとき ・・・ プログラム実行時に1度だけその値で初期化される
 明示的に初期化しないとき ・・・ 自動的に 0 で初期化される

4. 配列の場合

 上記の 1, 2, 3 の扱いと同様です。 初期値の数が配列要素数と異なるときの扱いについては次の通りです。
  初期値の数 < 要素数のとき ・・・ 上記 1, 2, 3 とも残りの要素は 0 になる。
  初期値の数 > 要素数のとき ・・・ 上記 1, 2, 3 ともコンパイル・エラーになる。

変数を使う前には値を入れて

 ローカル変数はもちろんのこと、自動で初期化される変数でも、使う前には適切に値を入れて使う方がよいと思います。
 scanf や代入などにより必ずデータを入れて使う場合を除き、明示的に初期化しておくと、見つけにくいバグや不要なトラブルを避けたり、処理内容を明確にすることができます。

(今回のクイズはありません)

前回のクイズの答え: (2)の 0.0 (前回の問題を見る
 構造体の初期化では、初期値を指定していないメンバは 0 で初期化されます。
 なお、構造体のメンバ名を指定して初期値を指定する書き方もできます。
shape_t stars[] = { { .name="ブラッド・ピット", .height=183.2, .weight=73.4, .bmi=0.0 }
                       :