[KNK] chapter 8 : 배열
1. 1차원 배열
배열은 특정 개수의 원소들을 연속적으로 저장하는 자료구조이다. 파이썬의 리스트와 달리 C언어의 배열은 원소들이 같은 형을 가져야 한다. 이는 C언어에서의 배열은 메모리에서 연속적으로 할당되기 때문이다.
그렇다면 C언어에서 배열을 선언할 때에 우선적으로 배열 원소의 형과 크기를 결정해주어야 한다는 점을 자연스럽게 이해할 수 있다.
C언어에서는 배열에서 첨자의 범위를 확인하는 기능을 강제하지 않는다고 한다. 파이썬에서 배열의 범위를 벗어나는 경우 오류를 발생시키는 것과 달리, C에서 배열의 범위를 벗어나게 되면 어떤 예상할 수 없는 값을 출력될 수 있다는 것이다. 실제로 온라인 C 컴파일러로 아래의 코드를 실행시켜 보면 이상한 값이 출력되는 것을 확인할 수 있다.
#include <stdio.h>
int main() {
int a[3] = {1, 2, 3};
printf("%d", a[3]);
return 0;
}
// OUTPUT : 10396928 !?
배열은 선언과 함께 초기화 할 수 있다. 바로 위 코드에서도 중괄호를 활용하여 배열 a를 초기화시킨 모습을 확인할 수 있다. 이는 파이썬의 리스트가 대괄호를 이용한다는 것과 구별된다. 이외에 초기화 관련하여 기억하면 좋을 사항들을 정리해 본다.
- 만약 array initializer가 배열보다 짧은 int a[3] = {1, 2}; 와 같은 경우에는 나머지 원소들은 0이라는 값을 갖게 된다.
- 위와 달리 중간 위치의 원소에 값을 넣어주고 나머지는 기본값으로 초기화하고 싶은 경우가 있을 수 있는데, C99의 designated initializer가 이를 가능케 한다. 예를 들어 int a[3] = {[2] = 3, [0] = 1}; 과 같이 작성한다면 배열 a는 {1, 0, 3}으로 초기화된다.
- 또한 array initializer가 존재한다면 배열의 길이를 굳이 적을 필요가 없이 int a[] = {1,2,3};처럼 작성할 수 있다.
- 만약 designated initializer 방식으로 초기화 하는 경우에는 가장 큰 지정자의 값을 통해 배열의 길이를 추론하게 된다. 예를 들어 int a[] = {[2] = 3, [0] = 1}; 의 경우 가장 큰 지정자가 2이므로 배열의 크기가 3임을 추론한다는 것이다.
2. 다차원 배열
C언어에서는 포인터의 배열을 통해 다차원 자료를 좀더 유연하게 저장할 수 있기 때문에 다차원 배열의 중요도가 다른 언어에 비해 상대적으로 떨어진다고 한다. 여기서는 C언어의 다차원 배열이 실질적으로 컴퓨터 메모리에 어떻게 저장되는지를 확인해보자.
예를들어 2차원 배열 int arr[n][m]; 의 경우 n행 m열의 2차원 표의 형태로 저장될 것 같은 기분이 든다. 그러나 실제로는 1차원 배열에서 처럼 연속적인 메모리 공간에 할당되는데, 이때 C는 배열을 행 우선 순서로 저장하게 된다. 아래 교재의 그림을 참고하면 쉽게 이해할 수 있다.
3. 가변크기 배열
C 언어에서는 배열이 고정된 크기를 가지며, 배열의 크기는 상수값이나 상수 표현식으로 지정해야 한다. 그러나 C99에서는 가변 크기 배열(VLA)을 도입하여 배열의 크기를 런타임에 동적으로 결정할 수 있도록 하였다. 이를 통해 사용자 입력이나 계산된 값을 배열의 크기로 사용할 수 있다. VLA는 함수 내에서 선언할 수 있으며, 함수가 호출될 때마다 다른 크기를 가질 수 있는 장점이 있다. 그러나 VLA는 스택에 할당되므로, 큰 배열 크기를 사용할 경우 스택 오버플로우의 위험이 있으며, C89/C90과의 호환성 문제도 고려해야 한다.
VLA 예시코드는 다음과 같다.
#include <stdio.h>
int main() {
int n;
// 사용자로부터 배열의 크기를 입력받음
printf("Enter the size of the array: ");
scanf("%d", &n);
// 가변 크기 배열 선언
int arr[n]; // C99에서 VLA를 사용하여 배열 크기를 n으로 설정
// 배열에 값 할당
for (int i = 0; i < n; i++) {
arr[i] = i * 2; // 예시로 짝수값 할당
}
// 배열 값 출력
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}