본문 바로가기
Programming

C 배열과 문자열

by 나무수피아는 지식의 가지를 뻗어가는 공간입니다. 2025. 8. 15.
반응형
배열과 문자열

1차원 배열

   배열(Array)은 동일한 데이터 타입을 가진 여러 개의 데이터를 하나의 이름으로 묶어 관리할 수 있는 자료구조입니다. C 언어에서 배열은 연속적인 메모리 공간에 데이터를 순차적으로 저장하며, 한 번 선언하면 크기가 고정됩니다. 따라서 배열은 정적 메모리 할당의 대표적인 예시입니다. 배열을 사용하면 개별 변수 여러 개를 따로 선언하는 대신, 하나의 배열 변수로 다수의 값을 편리하게 관리할 수 있습니다.

1차원 배열은 선형적인 데이터 구조로서, 데이터를 일렬로 나열한 형태입니다. 배열의 각 요소(element)는 인덱스(index)를 통해 접근할 수 있는데, C 언어의 배열 인덱스는 0부터 시작합니다. 즉, 첫 번째 원소의 인덱스는 0이며, 마지막 원소의 인덱스는 (배열 크기 - 1)입니다.

1차원 배열 선언과 초기화

1차원 배열을 선언하는 기본 문법은 다음과 같습니다.

int arr[5]; // 정수형 배열 선언 (크기 5)

선언과 동시에 초기화도 가능합니다:

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

만약 배열 크기보다 초기화 리스트의 원소가 적으면, 나머지 원소들은 0으로 자동 초기화됩니다:

int arr[5] = {1, 2};  // arr[2], arr[3], arr[4]는 0

크기를 명시하지 않고 초기화 리스트만 제공하면, 배열 크기는 리스트 길이에 맞춰 자동 결정됩니다:

int arr[] = {10, 20, 30};  // 크기 3

배열 원소 접근과 사용

배열의 각 원소는 인덱스 연산자를 사용해 접근할 수 있습니다:

int value = arr[2];  // 세 번째 원소 접근, value는 3

배열 인덱스는 0부터 시작하므로 arr [0]은 첫 번째 원소, arr [4]는 다섯 번째 원소가 됩니다. 인덱스가 배열 크기를 벗어나면 정의되지 않은 동작이 발생하며, 이는 심각한 버그와 보안 문제를 일으킬 수 있습니다.

배열과 포인터

C 언어에서 배열명은 배열의 첫 번째 원소의 주소를 가리키는 포인터처럼 동작합니다. 따라서 배열과 포인터는 밀접한 관계를 가지고 있습니다.

int *p = arr;  // arr의 첫 원소 주소를 p에 저장
int first = *p; // arr[0]과 동일

포인터 산술을 이용해 배열 내 요소들을 순회할 수 있습니다:

for (int i = 0; i < 5; i++) {
    printf("%d ", *(p + i));
}

배열과 포인터를 올바르게 이해하는 것은 C 프로그래밍에서 매우 중요합니다.

문자 배열과 문자열 처리

C 언어에서 문자열은 문자(character)의 배열로 표현되며, 문자열의 끝은 반드시 null 문자 ('\0')로 표시됩니다. 이 null 문자는 문자열의 끝을 알려주는 역할을 하며, 이를 통해 다양한 문자열 함수가 문자열의 길이를 알 수 있습니다.

문자 배열 선언과 초기화

문자열을 저장할 문자 배열을 선언하는 방법은 다음과 같습니다:

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

위 예제는 문자 하나하나를 명시적으로 초기화한 경우입니다. 하지만 일반적으로 문자열 리터럴을 직접 사용할 수 있습니다:

char str[6] = "Hello";  // 자동으로 마지막에 '\0' 추가

배열 크기를 생략하고 문자열 리터럴로 초기화하면 배열 크기는 문자열 길이 + 1(널 문자)로 자동 결정됩니다:

char str[] = "Hello";  // 크기 6

중요: 문자열을 저장하는 배열의 크기는 항상 문자열 길이보다 1 이상 커야 하며, 이는 문자열 끝을 표시하는 '\0'를 저장하기 위해 필요합니다.

문자열과 배열의 차이

문자 배열과 문자열은 밀접하지만 약간 다릅니다. 문자 배열은 문자들의 단순 집합이며, 문자열은 null 문자('\0')로 끝나는 문자 배열을 의미합니다. 따라서 문자열이 되려면 반드시 끝에 '\0'가 있어야 하며, 그렇지 않으면 문자열 함수 사용 시 문제가 발생합니다.

예를 들어, char arr [5] = {'H', 'e', 'l', 'l', 'o'};는 널 문자가 없어 문자열로 간주하지 않습니다. 반면 char str [6] = "Hello";는 올바른 문자열입니다.

문자열 관련 함수

C 표준 라이브러리에는 문자열을 다루기 위한 여러 유용한 함수들이 string.h 헤더 파일에 포함되어 있습니다. 이 함수들을 사용하면 문자열 복사, 비교, 길이 계산, 연결 등을 쉽게 처리할 수 있습니다.

strlen 함수

strlen() 함수는 문자열의 길이(문자 개수)를 계산하여 반환합니다. 문자열 끝을 나타내는 '\0' 문자는 길이에 포함하지 않습니다.

#include <string.h>
char str[] = "Hello";
int len = strlen(str);  // len은 5

주의: 문자열이 반드시 널 문자로 끝나야 하며, 그렇지 않으면 strlen()이 무한 루프에 빠질 수 있습니다.

strcpy 함수

strcpy() 함수는 한 문자열을 다른 문자열에 복사합니다. 복사 대상 배열의 크기가 복사할 문자열보다 충분히 커야 합니다.

#include <string.h>
char src[] = "Hello";
char dest[10];
strcpy(dest, src);  // dest는 "Hello"로 복사됨

만약 복사 대상 배열이 작으면, 메모리 오류 및 버퍼 오버플로우가 발생할 수 있으니 주의해야 합니다.

strcat 함수

strcat() 함수는 두 문자열을 이어 붙입니다. 첫 번째 문자열 끝에 두 번째 문자열을 덧붙이며, 첫 번째 문자열이 충분히 큰 배열이어야 합니다.

#include <string.h>
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);  // str1은 "Hello World"로 변경

중요: strcat() 사용 시 배열 크기를 항상 확인해야 하며, 안전한 문자열 결합을 위해 strncat() 사용을 권장합니다.

strcmp 함수

strcmp() 함수는 두 문자열을 비교합니다. 같으면 0을 반환하며, 다르면 사전 순서에 따라 음수나 양수를 반환합니다.

#include <string.h>
int result = strcmp("apple", "banana");  // result는 음수 (apple이 banana보다 사전순 앞임)

strcmp()는 문자열이 같은지 여부뿐 아니라 사전적 순서도 판단할 때 사용됩니다. 대소문자 구분이 필요 없는 비교는 strcasecmp()를 사용합니다(플랫폼에 따라 지원 여부 다름).

안전한 문자열 함수

전통적인 strcpy(), strcat() 함수들은 버퍼 크기 확인이 없어서 버퍼 오버플로우 위험이 큽니다. 이를 보완하기 위해 C11 표준부터는 strcpy_s(), strcat_s() 같은 안전한 함수들이 추가되었으며, POSIX 환경에서는 strncpy(), strncat() 등을 사용해 복사 및 연결 시 최대 길이를 제한할 수 있습니다.

문자열 복사 예제: strcpy vs strncpy

#include <string.h>
char src[] = "Hello, World!";
char dest1[20];
char dest2[6];

strcpy(dest1, src);       // dest1에 전체 문자열 복사
strncpy(dest2, src, 5);   // dest2에 "Hello"까지만 복사
dest2[5] = '\0';          // 널 문자 직접 추가 필요

strncpy()는 지정된 길이만큼만 복사하고, 만약 복사할 문자열이 길면 널 문자를 자동으로 추가하지 않으므로 직접 추가해야 합니다.

문자열 처리 시 유의점

  • 문자열 배열 크기는 반드시 충분히 크게 선언해야 하며, null 문자('\0') 공간을 포함해야 합니다.
  • 문자열 함수 사용 전, 문자열이 반드시 '\0'로 끝나는지 확인해야 합니다.
  • 버퍼 오버플로우 방지를 위해 안전한 함수 또는 길이 제한 함수 사용을 권장합니다.
  • 문자열 비교는 대소문자 구분, 로케일(locale) 설정에 따라 다르게 작동할 수 있습니다.
반응형

'Programming' 카테고리의 다른 글

C 파일 입출력  (53) 2025.08.17
C 포인터 기초  (63) 2025.08.16
C 함수  (63) 2025.08.14
C 다차원 배열과 포인터  (62) 2025.08.13
C 고급 포인터  (75) 2025.08.12