C90 표준에서는 배열을 반드시 고정된 순서로 초기화해야 했습니다. 즉, 인덱스 0, 1, 2… 순서대로 값을 나열하는 방식이 유일했습니다. 그러나 C99 표준부터 지정 초기화(Designated Initialization) 기능이 도입되면서 원하는 순서대로 요소를 자유롭게 초기화할 수 있게 되었습니다. 초기화는 배열 인덱스 또는 구조체 멤버 이름을 사용해 수행할 수 있으며, 참고로 이 확장 기능은 GNU C++에서는 지원되지 않습니다.
배열 인덱스를 이용한 지정 초기화
특정 인덱스에 값을 지정하려면 다음과 같이 작성합니다.
int arr[6] = {[3] = 20, [5] = 40}; 또는
int arr[6] = {[3]20, [5]40};
위 코드는 아래와 동일한 의미입니다.
int arr[6] = {0, 0, 0, 20, 0, 40};
범위 지정 초기화
[first ... last] = value 구문을 사용하면 연속된 여러 요소에 한 번에 같은 값을 할당할 수 있습니다.
int arr[6] = {[2 ... 4] = 10};
결과는 다음과 같습니다.
int arr[6] = {0, 0, 10, 10, 10, 0};
만약 배열의 크기를 명시하지 않으면, 컴파일러는 가장 큰 인덱스 위치를 기준으로 배열 크기를 자동으로 결정합니다. 다음 예제 코드를 통해 더 자세히 살펴보겠습니다.
예제 코드
#include <stdio.h>
int main() {
int Array[] = {10, 20, 30, [3 ... 9] = 100, [10] = 65, 15, [80] = 50, [42] = 400 };
int i;
for (i = 0; i < 20; i++)
printf("%d ", Array[i]);
printf("\nArray[%d] = %d\n",80, Array[80]);
printf("Array[%d] = %d\n",42, Array[42]);
printf("Size of this array: %ld\n", sizeof(Array) / sizeof(Array[0]));
}
실행 결과
10 20 30 100 100 100 100 100 100 100 65 15 0 0 0 0 0 0 0 0 Array[80] = 50 Array[42] = 400 Size of this array: 81
위 예제에서 가장 큰 인덱스가 80이므로, 배열 전체 크기가 자동으로 81개 요소로 설정된 것을 확인할 수 있습니다. 명시적으로 초기화되지 않은 나머지 요소들은 모두 0으로 채워집니다.
구조체와 공용체의 지정 초기화
지정 초기화는 구조체(struct)나 공용체(union) 타입 객체에도 적용할 수 있습니다. 이 경우에는 멤버 변수 이름 앞에 점(.)을 붙여, 선언 순서와 무관하게 어떤 순서로든 초기화할 수 있습니다. 명확한 이해를 위해 아래 코드를 확인해 보세요.
예제 코드
#include <stdio.h>
struct myStruct {
int x;
float y;
char z;
};
int main() {
struct myStruct str1 = {.y = 2.324, .z = 'f', .x = 78};
struct myStruct str2 = {.z = 'r'};
printf ("x = %d, y = %f, z = %c\n", str1.x, str1.y, str1.z);
printf ("z = %c\n", str2.z);
}
실행 결과
x = 78, y = 2.324000, z = f z = r
str1은 선언된 순서(x, y, z)와 다르게 y, z, x 순서로 초기화했음에도 정상적으로 동작합니다. 또한 str2처럼 일부 멤버만 초기화하면, 나머지 멤버들은 자동으로 0으로 설정됩니다. 이처럼 지정 초기화를 활용하면 대규모 배열이나 구조체에서 필요한 값만 선택적으로 초기화할 수 있어 코드의 가독성과 유지보수성이 크게 향상됩니다.