C 언어에서 변수 길이 배열: 초보자 가이드
안녕하세요, 미래의 프로그래머 여러분! 오늘 우리는 C 언어의 Variable Length Arrays (VLAs)에 대한 흥미로운 여정을 시작할 것입니다. 프로그래밍에 처음 도전하는 분이라면 걱정하지 마세요 - 저는 친절한 안내자가 되어 단계별로 설명해 드릴게요. 그럼 시작해 볼까요!
변수 길이 배열이란?
시작하기 전에 변수 길이 배열(VLA)이 무엇인지 이해해 보겠습니다. 파티를 계획하고 있지만 얼마나 많은 손님들이 올지 모르겠다고 가정해 봅시다. 손님의 수에 따라 자동으로 크기를 조정할 수 있는 마법의 테이블이 있다면 얼마나 좋을까요? 그게 프로그래밍에서 VLA가 하는 일입니다!
변수 길이 배열은 실행 시간(프로그램이 실행되는 시점)에 크기가 결정되는 배열로, 컴파일 시간(프로그램이 실행 준비되는 시점)에 크기가 결정되는 배열이 아닙니다. 이 기능은 C99 표준에서 도입되었으며, 배열 생성에 더 많은 유연성을 제공합니다.
변수 길이 배열 생성하기
간단한 예제로 VLA를 생성해 보겠습니다:
#include <stdio.h>
int main() {
int n;
printf("얼마나 많은 숫자를 저장하고 싶으신가요? ");
scanf("%d", &n);
int numbers[n]; // 여기서 우리의 Variable Length Array를 생성합니다
printf("%d개의 숫자를 입력하세요:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &numbers[i]);
}
printf(" 입력하신 숫자: ");
for (int i = 0; i < n; i++) {
printf("%d ", numbers[i]);
}
return 0;
}
이 코드를 분해해 보겠습니다:
- 사용자에게 저장하고 싶은 숫자의 개수를 물어봅니다.
- 사용자가 입력한 크기
n
으로 배열numbers
를 생성합니다. - 루프를 사용하여
n
개의 숫자를 사용자로부터 입력받습니다. - 마지막으로 사용자가 입력한 모든 숫자를 출력합니다.
이게 VLA의 아름다움입니다 - 코드를 작성할 때 배열의 크기를 알 필요가 없습니다. 배열의 크기는 프로그램이 실행될 때 결정됩니다!
이차원 변수 길이 배열
이제 한 단계 더 나아가 이차원 VLA를 살펴보겠습니다. 결혼식의 좌석 배치도를 만들 때, 테이블의 수와 각 테이블의 좌석 수를 모르는 경우를 상상해 봅시다. 이차원 VLA가 이를 도와줄 수 있습니다!
예제를 보겠습니다:
#include <stdio.h>
int main() {
int tables, seats;
printf("테이블의 수는 얼마인가요? ");
scanf("%d", &tables);
printf("테이블에 몇 개의 좌석이 있을까요? ");
scanf("%d", &seats);
int seating[tables][seats]; // 우리의 2D Variable Length Array
// 좌석 번호 부여
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats; j++) {
seating[i][j] = i * seats + j + 1;
}
}
// 좌석 배치도 출력
printf("\n좌석 배치도:\n");
for (int i = 0; i < tables; i++) {
printf("테이블 %d: ", i + 1);
for (int j = 0; j < seats; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}
return 0;
}
이 예제에서:
- 사용자에게 테이블의 수와 각 테이블의 좌석 수를 물어봅니다.
- 사용자가 입력한 크기로 2D VLA
seating
을 생성합니다. - 좌석 번호를 부여하고 출력합니다.
이러한 유연성 덕분에 실행 시간에 따라 크기를 조정할 수 있는 좌석 배치도를 만들 수 있습니다!
이지ged 배열
이제는 더 흥미로운 부분으로 넘어가겠습니다. 결혼식에서 각 테이블에 다른 수의 좌석이 있다면 어떨까요? 각 서브 배열이 다른 길이를 가질 수 있는 이지ged 배열이 등장합니다.
C는 이지ged 배열을 직접 지원하지 않지만, VLA와 포인터를 사용하여 시뮬레이션할 수 있습니다. 다음은 그 방법입니다:
#include <stdio.h>
#include <stdlib.h>
int main() {
int tables;
printf("테이블의 수는 얼마인가요? ");
scanf("%d", &tables);
int *seats = malloc(tables * sizeof(int));
int **seating = malloc(tables * sizeof(int*));
// 각 테이블의 좌석 수 입력
for (int i = 0; i < tables; i++) {
printf("테이블 %d에 몇 개의 좌석이 있을까요? ", i + 1);
scanf("%d", &seats[i]);
seating[i] = malloc(seats[i] * sizeof(int));
}
// 좌석 번호 부여
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats[i]; j++) {
seating[i][j] = j + 1;
}
}
// 좌석 배치도 출력
printf("\n좌석 배치도:\n");
for (int i = 0; i < tables; i++) {
printf("테이블 %d: ", i + 1);
for (int j = 0; j < seats[i]; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}
// 할당된 메모리 해제
for (int i = 0; i < tables; i++) {
free(seating[i]);
}
free(seating);
free(seats);
return 0;
}
이 예제는 다음과 같습니다:
- 각 테이블의 좌석 수를 저장할 배열
seats
를 동적으로 할당합니다. - 포인터-to-포인터
seating
을 할당하여 이지ged 배열을 시뮬레이션합니다. - 각 테이블에 대해 메모리를 동적으로 할당합니다.
- 좌석 번호를 부여하고 출력합니다.
- 할당된 메모리를 해제하여 메모리 누수를 방지합니다.
이 접근 방식을 통해 각 테이블에 다른 수의 좌석을 가지는 배치도를 만들 수 있습니다 - 정말 유연합니다!
방법 표
우리가 예제에서 사용한 방법들의 빠른 참조 표입니다:
방법 | 설명 | 예제 |
---|---|---|
scanf() |
사용자로부터 형식화된 입력을 읽습니다 | scanf("%d", &n); |
printf() |
콘솔에 형식화된 출력을 출력합니다 | printf("안녕하세요, %s!", name); |
malloc() |
동적으로 메모리를 할당합니다 | int *arr = malloc(n * sizeof(int)); |
free() |
동적으로 할당된 메모리를 해제합니다 | free(arr); |
기억하시기로, 강력한 기능은 큰 책임을 동반합니다. VLA와 동적 메모리 할당은 강력한 도구이지만, 스택 오버플로우나 메모리 누수와 같은 문제를 피하기 위해 신중하게 사용해야 합니다.
그럼 이렇게 Variable Length Arrays in C에 대한 첫 걸음을 냈습니다. 연습이 완벽을 이루는 열쇠이니, 이 개념들을 실험해 보지 마세요. 행복한 코딩을 기원합니다!
Credits: Image by storyset