집합체 형식 초기화
집합체 형식은 구조체, 공용 구조체 또는 배열 형식입니다. 집합체 형식은 집합체 형식 멤버를 포함하며 초기화 규칙이 재귀적으로 적용됩니다.
구문
:
{
initializer-list
}
/* 집계 초기화의 경우 */
{
initializer-list
, }
:
initializer
initializer-list
,
initializer
initializer-list
는 쉼표로 구분된 이니셜라이저 목록입니다. 목록에서 각 이니셜라이저는 상수 식이거나 이니셜라이저 목록입니다. 따라서 이니셜라이저 목록은 중첩될 수 있습니다. 이 형식은 이 단원의 예제에서 나타난 것처럼 집합체 형식의 집합체 멤버를 초기화하는 데 유용합니다. 그러나 자동 식별자에 대한 이니셜라이저가 단일 식인 경우 상수 식일 필요가 없으며 단지 식별자에 할당하기 위한 올바른 형식을 가져야 합니다.
각 이니셜라이저 목록의 경우 상수 식의 값은 순서대로 집합체 변수의 해당 멤버에 할당됩니다.
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로 초기화하는 방식으로 네 번째 행까지 초기화합니다. 세 번째와 네 번째 행에 대한 이니셜라이저 목록은 마지막 상수 식 다음에 쉼표를 포함합니다. 마지막 이니셜라이저 목록({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 배열로 선언되며 각 구조체는 세 가지 멤버를 갖습니다. 초기화의 1행은 다음과 같이 nlist
의 첫 번째 행에 값을 할당합니다.
1행의 첫 번째 왼쪽 중괄호는
nlist
의 첫 집합체 멤버(즉,nlist[0]
)의 초기화를 시작하는 컴파일러로 신호를 보냅니다.두 번째 왼쪽 중괄호는
nlist[0]
의 첫 번째 집합체 멤버(즉,nlist[0][0]
의 구조체) 초기화를 시작함을 나타냅니다.첫 번째 오른쪽 중괄호는 구조체
nlist[0][0]
의 초기화를 종료하며 다음 왼쪽 중괄호는nlist[0][1]
의 초기화를 시작합니다.프로세스는 닫는 오른쪽 중괄호가
nlist[0]
의 초기화를 종료하는 줄의 끝까지 계속됩니다.
2행은 비슷한 방법으로 값을 nlist
의 두 번째 행으로 할당합니다. 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 */
};
이 생성에서 첫 번째 줄의 첫 번째 왼쪽 중괄호는 세 가지 구조체의 배열인 nlist[0]
의 초기화를 시작합니다. 값 1, 2, 3은 첫 번째 구조체의 멤버 3개에 할당됩니다. 다음 오른쪽 중괄호가 값 3 다음에 발견되는 경우 nlist[0]
의 초기화가 완료되며 세 가지 구조체 배열에서 나머지 두 구조체는 자동으로 0으로 초기화됩니다. 마찬가지로 { 4,5,6 }
은 nlist
의 두 번째 행에서 첫 번째 구조체를 초기화합니다. nlist[1]
의 나머지 두 구조체는 0으로 설정됩니다. 컴파일러가 다음 이니셜라이저 목록({ 7,8,9 }
)을 발견하는 경우 nlist[2]
초기화를 시도합니다. nlist
에는 두 행만 있으므로 이 시도는 오류가 발생합니다.
다음 예제에서 int
의 세 가지 x
멤버는 각각 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
의 첫 번째 행에 있는 세 가지 요소는 4.0으로 초기화되며 m
의 나머지 행에 있는 요소는 기본적으로 0.0으로 초기화됩니다.
union
{
char x[2][3];
int i, j, k;
} y = { {
{'1'},
{'4'}
}
};
이 예제에서는 공용 구조체 변수 y
가 초기화됩니다. 공용 구조체의 첫 번째 요소는 배열이므로 이니셜라이저는 집합체 이니셜라이저입니다. 이니셜라이저 목록 {'1'}
은 값을 배열의 첫 번째 행에 할당합니다. 하나의 값만 목록에 나타나므로 첫 번째 열의 요소는 문자 1
로 초기화되며 행의 나머지 두 요소는 기본적으로 값 0으로 초기화됩니다. 마찬가지로 x
의 두 번째 행에 있는 첫 번째 요소는 문자 4
로 초기화되며 행의 나머지 두 요소는 값 0으로 초기화됩니다.