C 언어 | 배열 | 배열 초기화


정수형 등의 변수와 마찬가지로 배열도 선언과 동시에 개별 요소를 초기화할 수 있다.

배열 변수의 초기화

일반 변수의 선언은 동시에 변수의 값을 초기화할 수 있었다. 배열도 이와 같이 선언시에 초기화할 수 있다. 배열처럼 간단한 형태(int 나 char 등)가 아닌 단순한 형태를 집합시킨 것 같은 기억 영역을 합성체라고 한다. 합성체를 초기화하려면 대괄호{}에서 초기 값의 목록을 지정한다. 이것은 다음과 같은 구문이다.

배열 초기화

형태 변명명[요소 수] = {제1요소 값, 제2요소 값, 제3요소 값, ...};

목록에서 지정하는 각 요소의 초기 값의 수는 배열의 요소 수를 초과해서는 안된다. 반대로, 초기값의 수가 배열의 크기보다도 적은 경우에는 나머지 요소가 0으로 초기화된다. 예를 들어, 다음은 int형 배열을 초기화 정의를 같이하고 있다.

int iArray[4] = { 10 , 100 , 1000 , 10000 };

이 배열은 처음부터 10, 100, 1000, 10000이라는 값으로 초기화된다. 이와 같이, 배열의 각 요소의 값이 미리 결정되어 있다면 이니셜라이저를 사용하면 소스 코드를 간략해 진다.

코드1

#include <stdio.h>

int main() {
  int iArray[4] = { 10 , 100 , 1000 , 10000 } , iCount;
 for(iCount = 0 ; iCount < 4 ; iCount++)
   printf("iArray[%d] = %d\n" , iCount , iArray[iCount]);
 return 0;
}

코드1은 iArray 배열 변수를 선언과 동시에 초기화한다. for 문을 사용하여 이 배열의 값을 표시하고 있기 때문에, 프로그램을 실행하면 배열이 올바르게 초기화되었는지를 확인할 수있는 것이다.

목록의 값이 배열에 초기 값으로 주어지고 있는 것을 알 수 있다. 물론 부동 소수점에서도 초기화 방법은 동일하다.

char 형 배열을 문자열로 초기화하려면, 하나는 연속된 문자 상수로 초기화하는 방법이 있다. 이 때 C 언어의 문자열의 약속인 배열 끝에 NULL 문자의 제로하는 것을 잊어서는 안된다.

코드2

#include <stdio.h>

int main() {
  char chStr[6] = { 'K' , 'i' , 't' , 't' , 'y' , 0 };
  printf("%s\n" , chStr);
  return 0;
}

코드2의 배열 변수 chStr은 초기화 문자열을 저장하고 있다. 초기화 목록에는 문자열의 각 문자를 문자 상수로 지정하고, 그 마지막에는 정수 0을 지정한다. 예상대로, 이 프로그램을 실행하면 Kitty라는 문자가 화면에 표시된다.

char 형의 배열 변수를 문자 배열로 초기화 할 경우 큰 따옴표로 묶어 초기화 할 수 있다. 리터럴 문자열 끝에 암시적으로 NULL 문자가 포함되어 있기 때문에, 그 만큼의 크기를 할당하는 것도 잊지 말자. 한국어와 같은 ASCII가 아닌 문자를 사용하면 문자 코드에 따라 다르지만 일반적으로 1문자가 2 바이트로 표현되므로 주의가 필요하다.

코드3

#include <stdio.h>

int main() {
 char chStr[6] = "Kitty";
  printf("%s\n" , chStr);
  return 0;
}

코드3은 프로그램으로 코드2와 동일하다. chStr 초기화 연속된 문자 상수가 아니라 리터럴 문자열을 사용한다는 점에서 코드2와 다르다. 문자 배열의 char 형 배열 변수를 초기화하려면 이것이 가장 편리한 작성법이다.

다차원 배열의 초기화

다차원 배열의 초기화를 시도할 경우 1차원 배열의 초기화보다 다소 복잡하다. 다차원의 경우는 그 차원 수만 중괄호를 {} 지정하여 각 차원의 목록을 중첩하여 초기화할 수 있다. 예를 들어, 2차원 배열의 경우는 다음과 같이 초기화한다.

int iArray[2][2] = { {1 , 2} , { 3 , 4 } };

이 경우, 첫번째 {는 iArray 초기화를 나타내며, 다음에 {는 iArray[0] 초기화 리스트라는 구조로 되어 있다. 즉, { 1, 2 }iArray[0] [0]iArray[0][1]을 초기화한다. 마찬가지로, 다음의 { 3, 4 }iArray[1]을 초기화한다. 배열의 수보다 목록의 수가 적은 경우, 나머지는 0으로 초기화된다.

코드4

#include <stdio.h>

int main() {
 int iCount1 , iCount2;
  int iArray[3][3] = {
    { 2 , 4 } ,
   { 8 , 16 , 32 }
 };

  for(iCount1 = 0 ; iCount1 < 3 ; iCount1++) {
    for(iCount2 = 0 ; iCount2 < 3 ; iCount2++) {
      printf("iArray[%d][%d] = %d\n" ,
       iCount1 , iCount2 , iArray[iCount1][iCount2]);
    }
 }
 return 0;
}

배열의 초기화에 주목한다. { 2, 4 }iArray[0]을 초기화하고 있지만 iArray[0][2]의 초기값이 존재하지 않기 때문에 iArray[0][2]는 0으로 초기화되어 있다. 다음 줄의 { 8, 16, 32 }iArray[1]을 초기화한다. 초기화는 여기서 종료하고 있기 때문에 iArray[2] 초기화 리스트는 존재하지 않는다. 따라서 iArray[2]는 모두 0으로 초기화되어 있다. 이것은 실행 결과를 보면 분명하다.

코드4에서 나타낸 초기화 방법은 {}를 중첩하고 있지만, 다음과 같이 하나의 리스트로 초기화할 수 있다.

int iArray[2][2] = { 1 , 2 , 3 , 4 };

이 경우, 배열의 처음부터 순서대로 목록의 값으로 초기화된다. 처음에는 iArray[0]에서 초기화된 목록의 처음 두 요소가 사용된다. 즉, iArray[0][0]이 1로, iArray[0][1]가 2로 초기화되는 것이다. 그리고 다음의 요소에서 iArray[1]가 초기화되는 순서이다. 이 경우 역시 배열의 수보다 목록의 값이 적으면 나머지는 0으로 초기화된다.

코드5

#include <stdio.h>

int main() {
  int iCount1 , iCount2;
  int iArray[3][3] = { 
   2 , 4 , 8 , 16 , 32 , 64 , 128 , 256
  };

  for(iCount1 = 0 ; iCount1 < 3 ; iCount1++) {
    for(iCount2 = 0 ; iCount2 < 3 ; iCount2++) {
      printf("iArray[%d][%d] = %d\n" ,
       iCount1 , iCount2 , iArray[iCount1][iCount2]);
    }
 }
 return 0;
}

배열이 목록의 상위부터 순서대로 올바르게 초기화되는 것을 확인할 수 있다. 이니셜라이저으로 지정하는 값은 8개이고, 배열의 요소 수 9보다 적기 때문에 마지막 iArray[2][2]는 0으로 초기화되어 있다. 이러한 다차원 배열의 초기화는 예를 들어 문자열 테이블을 배열로 제공할 때 등에 편리하다.

코드6

#include <stdio.h>

int main() {
 char chStr[3][8] = {
    "Kitty" , "Kitten" , "Feline"
 };
  printf("%s : %s : %s\n" , chStr[0] , chStr[1] , chStr[2]);
 return 0;
}

이 프로그램은 다차원 배열에서 문자열 배열을 생성하고 있다. 문자열은 자체가 문자 배열이므로 문자열의 배열을 만들 수 있기에 자동으로 2차원 배열을 만들어야 하는 것이 된다.

요소 수의 생략

초기화를 지정하는 배열의 경우, 컴파일러는 초기화 목록에서 배열처럼 그 수를 예상 할 수 있다. 따라서 0으로 초기화하는 여분의 요소를 보유하려는 경우를 제외하고 초기화를 지정하는 배열의 크기를 직접 지정하는 것은 중복으로 간주된다. 초기화 식에서 배열의 요소 수를 제한할 수 있는 경우, 배열의 선언에서 크기를 생략할 수 있다. 다만, 그 경우에도 []를 생략할 수 없다.

int iArray[ ] = { ... }

이것은 문자열을 배열 변수에 초기화할 때 등에 유용할 것이다. 요소 수를 생략하면 잘못된 크기를 할당해 버리는 실수를 피할 수 있다.

코드7

#include <stdio.h>

int main() {
  char chStr[] = "Kitty on your lap";
 printf("%s\n" , chStr);
  return 0;
}

코드7는 chStr 배열 변수의 요소 수를 생략한다. 컴파일러는 초기화 “Kitty on your lap"를 배열에 저장하는데 필요한 크기를 계산하여 최적의 요소 수를 지정해 준다.