初期化
オブジェクトの宣言は初期化と呼ばれる処理を通して初期値を提供することができます。
それぞれの宣言子に対して、以下のいずれかの初期化子を使用できます (省略しない場合)。
= expression
|
(1) | ||||||||
= { initializer-list }
|
(2) | ||||||||
initializer-list は空でないコンマ区切りの initializer のリストであり (最後にもコンマを付けても構いません)、それぞれの初期化子は以下のいずれかの形式を取ります。
| expression | (1) | ||||||||
{ initializer-list }
|
(2) | ||||||||
designator-list = initializer
|
(3) | (C99以上) | |||||||
|
designator-list は ノート: 初期化子の他、複合リテラルに波括弧で囲まれた initializer-list が現れることもあります。 これは以下の形式の式です。
|
(C99以上) | |||||||||||||||||||||||
説明
初期化はオブジェクトに格納される初期値を指定します。
明示的な初期化
初期化子が指定されている場合、
暗黙の初期化
初期化子が指定されていない場合、
- ポインタはその型のヌルポインタに初期化されます。
- 整数型のオブジェクトは符号なしのゼロに初期化されます。
- 浮動小数点型のオブジェクトは正のゼロに初期化されます。
- 配列、構造体、共用体のメンバは再帰的に上記のように初期化され、パディングビットはすべてゼロに初期化されます。
- (ヌルポインタおよび浮動小数点のゼロがオールゼロのビット表現を持つプラットフォームでは、静的オブジェクトに対するこの形式の初期化は通常、プログラムイメージの .bss セクションに確保することで実装されます)。
ノート
静的またはスレッドローカル記憶域期間のオブジェクトを初期化する場合、初期化子のすべての expression は定数式または文字列リテラルでなければなりません。
初期化子は不完全型、 VLA のオブジェクトや、リンケージを持つブロックスコープのオブジェクトの宣言では、使うことができません。
関数の仮引数の初期値は、初期化ではなく、関数呼び出しの実引数から代入されるかのように確立されます。
標準ライブラリの呼び出しに対する引数として不定値を使用した場合、動作は未定義です。 そうでなければ、不定値を含む式の結果は不定値です (例えば int n;、 n をそれ自身と比較して等しいかどうかはわかりませんし、読み取るたびに異なる値が得られる可能性もあります)。
例
#include <stdlib.h>
int a[2]; // a を {0, 0} に初期化します。
int main(void)
{
int i; // i を不定値に初期化します。
static int j; // j を 0 に初期化します。
int k = 1; // k を 1 に初期化します。
// int x[3] を 1,3,5 に初期化します。
// int* p を &x[0] に初期化します。
int x[] = { 1, 3, 5 }, *p = x;
// w (構造体2個の配列) を { { {1,0,0}, 0}, { {2,0,0}, 0} } に初期化します。
struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2};
// ローカル変数に対して関数呼び出し式を使用できます。
char* ptr = malloc(10);
free(ptr);
// エラー。 静的記憶域期間を持つオブジェクトは定数初期化子を要求します。
// static char* ptr = malloc(10);
// エラー。 VLA は初期化できません。
// int vla[n] = {0};
}
参考文献
- C11 standard (ISO/IEC 9899:2011):
- 6.7.9 Initialization (p: 139-144)
- C99 standard (ISO/IEC 9899:1999):
- 6.7.8 Initialization (p: 125-130)
- C89/C90 standard (ISO/IEC 9899:1990):
- 6.5.7 Initialization
関連項目
初期化 の C++リファレンス
|