集計型は、構造体、共用体、または配列型です。 集計型に集計型のメンバーが含まれている場合、初期化規則は再帰的に適用されます。
構文
initializer:
{
initializer-list
} /* 集計初期化の場合 */
{
initializer-list
, }
initializer-list:
initializer
initializer-list
,
initializer
initializer-listは、コンマで区切られた初期化子の一覧です。 リスト内の各初期化子は、定数式または初期化子リストです。 したがって、初期化子リストは入れ子にすることができます。 このフォームは、このセクションの例に示すように、集計型の集計メンバーを初期化する場合に役立ちます。 ただし、自動識別子の初期化子が 1 つの式である場合は、定数式である必要はありません。識別子への割り当てに適切な型が必要なだけです。
初期化子リストごとに、定数式の値が、集計変数の対応するメンバーに順番に割り当てられます。
initializer-listの値が集計型よりも少ない場合、集計型の残りのメンバーまたは要素は 0 に初期化されます。 明示的に初期化されていない自動識別子の初期値は未定義です。
initializer-listに集計型よりも多くの値がある場合は、エラーが発生します。 これらの規則は、各埋め込み初期化子リストと集計全体に適用されます。
構造体の初期化子は、同じ型の式か、中かっこ ({ }) で囲まれたメンバーの初期化子のリストです。 名前のないビット フィールド メンバーは初期化されません。
共用体が初期化される場合、 initializer-list は単一の定数式である必要があります。 定数式の値は、共用体の最初のメンバーに割り当てられます。
配列のサイズが不明な場合、初期化子の数によって配列のサイズが決まります。その型は完全になります。 C で初期化子の繰り返しを指定したり、前のすべての値を指定せずに配列の途中で要素を初期化したりする方法はありません。 プログラムでこの操作が必要な場合は、アセンブリ言語でルーチンを記述します。
初期化子の数は、配列のサイズを設定できます。
int x[ ] = { 0, 1, 2 }
ただし、サイズを指定し、間違った数の初期化子を指定すると、コンパイラによってエラーが生成されます。
Microsoft 固有の仕様
配列の最大サイズは、 size_tによって定義されます。
Microsoft 固有の仕様はここまで
例示
この例では、配列の初期化子を示します。
int P[4][3] =
{
{ 1, 1, 1 },
{ 2, 2, 2 },
{ 3, 3, 3,},
{ 4, 4, 4,},
};
このステートメントでは、 P を 4 対 3 の配列として宣言し、最初の行の要素を 1 に初期化し、2 行目の要素を 2 に初期化します。また、4 行目まで初期化します。 3 行目と 4 行目の初期化子リストには、最後の定数式の後にコンマが含まれています。 最後の初期化子リスト ({4, 4, 4,},) にもコンマが続きます。 これらの余分なコンマは許可されますが、必須ではありません。 定数式を互いに区切るコンマと、ある初期化子リストを別の初期化子リストから区切るコンマのみが必要です。
集計メンバーに埋め込み初期化子リストがない場合は、サブ集計の各メンバーに順番に値が割り当てられます。 したがって、前の例の初期化は次の例と同じです。
int P[4][3] =
{
1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4
};
中かっこは、リスト内の個々の初期化子の周りに表示され、例を明確にするのに役立ちます。
集計変数を初期化するときは、中かっこと初期化子リストを適切に使用するように注意する必要があります。 次の例では、コンパイラによる中かっこの解釈について詳しく説明します。
typedef struct
{
int n1, n2, n3;
} triplet;
triplet nlist[2][3] =
{
{ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }, /* Row 1 */
{ { 10,11,12 }, { 13,14,15 }, { 16,17,18 } } /* Row 2 */
};
この例では、 nlist は構造体の 2 対 3 の配列として宣言され、各構造体には 3 つのメンバーが含まれます。 初期化の行 1 は、次のように、 nlistの最初の行に値を割り当てます。
行 1 の最初の左中かっこは、
nlist(つまり、nlist[0]) の最初の集計メンバーの初期化が開始されていることをコンパイラに通知します。2 番目の左中かっこは、
nlist[0]の最初の集計メンバー (つまり、nlist[0][0]の構造体) の初期化が開始されていることを示します。最初の右中かっこは構造体
nlist[0][0]の初期化を終了し、次の左中かっこはnlist[0][1]の初期化を開始します。このプロセスは行の終わりまで続行され、右中かっこが右中かっこで
nlist[0]の初期化が終了します。
行 2 は、同様の方法で nlist の 2 番目の行に値を割り当てます。 行 1 と行 2 の初期化子を囲む中かっこの外側のセットが必要です。 外側の中かっこを省略した次の構造では、エラーが発生します。
triplet nlist[2][3] = /* THIS CAUSES AN ERROR */
{
{ 1, 2, 3 },{ 4, 5, 6 },{ 7, 8, 9 }, /* Line 1 */
{ 10,11,12 },{ 13,14,15 },{ 16,17,18 } /* Line 2 */
};
この構成では、1 行目の最初の左中かっこは、3 つの構造体の配列である nlist[0]の初期化を開始します。 値 1、2、および 3 は、最初の構造体の 3 つのメンバーに割り当てられます。 次の右中かっこが検出されると (値 3 の後)、 nlist[0] の初期化が完了し、3 構造体配列内の残りの 2 つの構造体が自動的に 0 に初期化されます。 同様に、 { 4,5,6 } は、 nlistの 2 行目の最初の構造体を初期化します。
nlist[1]の残りの 2 つの構造体は 0 に設定されます。 コンパイラは、次の初期化子リスト ( { 7,8,9 } ) を検出すると、 nlist[2]の初期化を試みます。
nlistには 2 行しかないため、この試行によりエラーが発生します。
この次の例では、xの 3 つのint メンバーをそれぞれ 1、2、3 に初期化します。
struct list
{
int i, j, k;
float m[2][3];
} x = {
1,
2,
3,
{4.0, 4.0, 4.0}
};
list構造体では、mの最初の行の 3 つの要素は 4.0 に初期化され、mの残りの行の要素は既定で 0.0 に初期化されます。
union
{
char x[2][3];
int i, j, k;
} y = { {
{'1'},
{'4'}
}
};
この例では、共用体変数 yが初期化されます。 共用体の最初の要素は配列であるため、初期化子は集計初期化子です。 初期化子リスト {'1'} は、配列の最初の行に値を割り当てます。 リストには 1 つの値しか表示されないので、最初の列の要素は文字 1に初期化され、行の残りの 2 つの要素は既定で値 0 に初期化されます。 同様に、 x の 2 番目の行の最初の要素は文字 4に初期化され、行の残りの 2 つの要素は値 0 に初期化されます。