본문 바로가기
카테고리 없음

C언어 - 배열과 문자열

by kik328288 2026. 5. 3.

C언어 배열 (문자열, strlen, 실기)

배열은 같은 자료형의 데이터를 한 묶음으로 관리하는 가장 기본적인 자료구조이며, 문자열은 그 배열 위에서 만들어지는 가장 자주 쓰이는 응용 형태이다. C언어는 별도의 문자열 자료형을 제공하지 않고 char 배열을 문자열로 사용하기 때문에, 배열과 문자열은 사실상 같은 메커니즘을 다른 관점에서 다루는 두 얼굴이라고 할 수 있다(출처: cppreference — Arrays). 두 개념을 정확히 이해해야 메모리 동작·포인터 연산·표준 라이브러리 함수가 모두 자연스럽게 연결된다. 정보처리기사 실기에서도 배열의 초기화 결과와 문자열 함수의 동작을 묻는 문제가 매회 출제되므로, 본 글은 코드 예시와 함께 핵심 개념을 한 번에 정리한다. 제가 학교 C언어 첫 학기에 가장 자주 만난 사고가 char s[5] = "HELLO"; 같은 한 줄짜리 실수였는데, NULL 문자 한 바이트를 빠뜨려 배열 크기가 부족해진 뒤로는 "문자열은 사실 N+1바이트"라는 한 줄을 손끝으로 외우게 되었다.

 

배열의 선언, 초기화, 그리고 다차원 배열

배열(Array)이란 같은 자료형의 변수 여러 개를 메모리상에 연속적으로 배치하고 하나의 이름으로 묶어 관리하는 자료구조이다. C언어에서 배열을 선언할 때는 자료형 배열명[크기]; 형식을 사용하며, 크기는 컴파일 시점에 결정되어야 한다. 배열의 인덱스는 0부터 시작해 크기-1까지의 범위를 가지며, 이 범위를 벗어난 인덱스에 접근하면 정의되지 않은 동작(Undefined Behavior)이 발생해 프로그램이 비정상적으로 종료될 수 있다. 여기서 정의되지 않은 동작이란 C 표준이 결과를 보장하지 않는 상태로, 컴파일러·환경·실행 시점에 따라 결과가 모두 달라질 수 있는 잠재적 사고의 근원을 가리킨다.

배열은 선언과 동시에 초기화할 수 있으며, 초기화 방법에 따라 미세한 차이가 발생한다. 시험에서 자주 묻는 패턴이므로 정확히 외워두어야 한다.

int a[5] = {1, 2, 3, 4, 5};   // 모든 원소 명시
int b[5] = {1, 2};             // 나머지는 0으로 초기화 → {1, 2, 0, 0, 0}
int c[5] = {0};                // 모든 원소 0으로 초기화
int d[] = {1, 2, 3};           // 크기 자동 결정 → 크기 3
int e[5];                      // 초기화 X → 쓰레기 값

핵심 포인트는 두 가지이다. 첫째, 일부만 초기화하면 나머지는 자동으로 0이 채워진다. 둘째, 크기를 비워두면 컴파일러가 초기화 값의 개수만큼 자동으로 크기를 결정한다. 다만 e처럼 초기화하지 않은 지역 배열은 쓰레기 값을 가지므로 반드시 사용 전에 초기화해야 한다.

다차원 배열은 배열의 배열로, 행렬이나 격자 형태의 데이터를 다룰 때 사용된다. 가장 흔한 형태가 2차원 배열이며 자료형 배열명[행][열]; 형식으로 선언한다.

int mat[2][3] = { {1, 2, 3}, {4, 5, 6} };
printf("%d\n", mat[0][1]);  // 2
printf("%d\n", mat[1][2]);  // 6

2차원 배열은 메모리상 행 우선(Row-major) 방식으로 저장된다. 여기서 행 우선이란 같은 행의 원소를 먼저 연속해서 배치한 뒤 다음 행으로 넘어가는 메모리 배치 방식을 의미하는데, 이 특성 때문에 같은 행 안에서의 순회가 다른 행으로 점프하는 것보다 캐시 적중률 측면에서 훨씬 효율적이다. 솔직히 이건 예상 밖이었는데, 학교 실험에서 같은 2중 반복을 (i,j) 순서로 돌리는 것과 (j,i) 순서로 돌리는 것의 실행 시간이 3~5배까지 차이 나는 모습을 직접 본 후로는 캐시 친화성이 단순한 이론이 아니라는 점을 받아들였다.

문자열 처리 — char 배열과 표준 함수

C언어에서 문자열은 별도의 자료형이 아니라 마지막에 NULL 문자(\0)가 붙은 char 배열이다. NULL 문자는 ASCII 코드 0이며, 문자열의 끝을 표시하는 종료 신호로 작동한다. 따라서 "HELLO"라는 5글자 문자열은 실제로는 6바이트(H, E, L, L, O, \0)를 차지한다는 사실을 정확히 이해해야 한다.

char s1[] = "HELLO";              // 6바이트 (NULL 포함)
char s2[10] = "HELLO";             // 10바이트 (나머지는 \0)
char s3[] = {'H','E','L','L','O','\0'};  // s1과 동일
char *s4 = "HELLO";                // 문자열 리터럴 포인터 (읽기 전용)

s1과 s4는 비슷해 보이지만 결정적인 차이가 있다. s1은 스택에 할당되는 수정 가능한 char 배열이고, s4는 데이터 영역의 읽기 전용 문자열 리터럴을 가리키는 포인터이다. s4[0] = 'h'처럼 수정하려고 하면 런타임 오류가 발생하므로 주의해야 한다.

C 표준 라이브러리는 string.h 헤더에 다양한 문자열 함수를 제공한다. 시험에 자주 출제되는 핵심 함수는 네 가지이다(출처: cppreference — string.h).

함수 동작 주의점
strlen(s) NULL 제외 문자열 길이 NULL 까지 가서 멈춤
strcpy(dest, src) src를 dest로 복사 dest 크기 충분해야 함
strcmp(s1, s2) 같으면 0, 다르면 음/양수 사전식 비교
strcat(dest, src) dest 끝에 src 이어붙임 dest 크기 충분해야 함

strcpystrcat은 대상 배열의 크기가 충분한지 사용자가 직접 확인해야 한다. 크기를 초과해 쓰면 인접 메모리를 침범하는 버퍼 오버플로(Buffer Overflow)가 발생하며, 이는 가장 빈번한 보안 취약점 중 하나이다. 여기서 버퍼 오버플로란 할당된 메모리 경계를 넘어 쓰는 모든 종류의 메모리 침범을 의미하며, 1988년 모리스 웜부터 현재까지 가장 자주 악용되는 공격 표면이다. 안전한 대안으로 strncpy, strncat, strncmp 같은 n자 제한 버전이 제공되며, 현대 코드에서는 이러한 안전 버전이 권장된다.

정보처리기사 실기 빈출 배열·문자열 예제

정보처리기사 실기에서 배열과 문자열은 단골 출제 영역이다. 출제 패턴은 크게 네 가지로 정리된다.

유형 1 — 배열 부분 초기화 결과 추적.

int a[5] = {1, 2};
for (int i = 0; i < 5; i++) printf("%d ", a[i]);
// 출력: 1 2 0 0 0

유형 2 — 2차원 배열 대각선 합.

int m[3][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
int sum = 0;
for (int i = 0; i < 3; i++) sum += m[i][i];
printf("%d\n", sum);     // 1 + 5 + 9 = 15

유형 3 — NULL 종료까지 직접 카운트(=strlen).

char s[] = "PROGRAM";
int len = 0;
while (s[len] != '\0') len++;
printf("%d\n", len);     // 7

유형 4 — 문자열 역순 출력.

char s[] = "HELLO";
int n = strlen(s);
for (int i = n - 1; i >= 0; i--) printf("%c", s[i]);
// 출력: OLLEH

유형 5 — 배열을 함수에 전달(원본 수정).

void modify(int arr[], int size) {
    for (int i = 0; i < size; i++) arr[i] *= 2;   // 원본 수정됨
}
int main(void) {
    int data[3] = {1, 2, 3};
    modify(data, 3);
    for (int i = 0; i < 3; i++) printf("%d ", data[i]);
    // 출력: 2 4 6
    return 0;
}

이 마지막 패턴이 가장 중요하다. 배열을 함수에 전달하면 배열 이름이 첫 원소의 주소로 변환되어 전달되기 때문에, 함수 내부에서의 수정이 호출자의 원본에 그대로 반영된다는 사실을 묻는다. 솔직히 제 경험상 학교 알고리즘 첫 시험에서 정확히 이 패턴을 틀려 점수를 한 줄로 까먹었고, 그 한 번의 실수가 "C에서 배열 인자는 사실상 포인터"라는 한 줄을 평생 잊지 않게 만들었다.


메타 디스크립션: C언어 배열의 선언과 초기화, 다차원 배열의 행 우선 메모리 구조, 문자열의 NULL 종료 표현과 string.h 표준 함수(strlen·strcpy·strcmp·strcat), 그리고 정보처리기사 실기 빈출 5패턴을 코드 예시와 함께 정리합니다.


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 블로그 이름