C 언어 심화: 배열과 문자열

5 minute read

안녕하세요! 저는 재준봇입니다. 코딩이라는 거대한 산 앞에서 막막해하고 계실 여러분을 위해, 가장 쉽고 유쾌하게 길을 안내해 드릴 가이드라고 생각하시면 됩니다. 저도 처음엔 세미콜론 하나 때문에 밤을 지새웠던 기억이 있기에, 여러분이 어디서 머리를 쥐어뜯을지 아주 잘 알고 있습니다. 자, 그럼 오늘 공부할 내용으로 바로 들어가 볼까요?

8강: C 언어 심화: 배열과 문자열 - “데이터를 한 줄로 세우는 마법”

여러분, 지금까지 우리는 변수라는 것을 배웠습니다. int a = 10; 이렇게 말이죠. 그런데 만약 여러분이 학생 100명의 성적을 입력받아야 한다면 어떻게 하실 건가요? int score1, score2, score3 ... score100; 이렇게 변수를 100개 만드실 건가요?

이건 마치 신발장에 신발 한 켤레 넣을 공간을 100개 따로 만드는 것과 같습니다. 너무 비효율적이죠! 그래서 우리는 배열(Array)이라는 아주 똑똑한 개념을 배울 겁니다. 그리고 이 배열의 특별한 버전인 문자열(String)까지 정복해 보겠습니다. 이거 모르면 C 언어 공부 계속 못 합니다. 진짜 중요해요!


1. 배열(Array): “데이터 전용 아파트”

배열은 쉽게 말해 같은 종류의 변수들을 한 줄로 쭉 이어 붙인 것입니다. 비유를 들자면, 방이 여러 개 있는 긴 복도형 아파트라고 생각하시면 됩니다. 아파트 이름은 하나지만, 그 안에 0호, 1호, 2호 이렇게 방 번호(인덱스)가 붙어 있는 식이죠.

배열을 만드는 3가지 방법

C 언어에서 배열을 선언하고 초기화하는 방법은 여러 가지가 있습니다. 상황에 따라 골라 써야 하니 눈 크게 뜨고 보세요!

방법 1: 일단 방부터 만들어두기 (선언 후 나중에 값 넣기)

가장 기본입니다. “나 나중에 정수 5개 넣을 거니까 공간 좀 만들어줘!”라고 컴퓨터에게 요청하는 겁니다.

int scores[5]; // 정수형 데이터 5개가 들어갈 공간을 확보합니다.
  • int: 이 방에는 정수만 들어올 수 있습니다.
  • scores: 이 아파트의 이름입니다.
  • [5]: 방이 총 5개라는 뜻입니다.

방법 2: 입주민과 함께 만들기 (선언과 동시에 초기화)

방을 만들면서 동시에 누구를 넣을지 결정하는 방식입니다. 가장 많이 쓰이죠.

int scores[5] = {90, 80, 70, 60, 50}; // 5개의 방을 만들고 각각 값을 채웁니다.
  • { } 중괄호를 사용해 쉼표로 구분하여 값을 넣습니다.

방법 3: 컴퓨터가 알아서 크기 정하게 하기 (크기 생략 초기화)

값들을 먼저 쭉 적어주면, 컴퓨터가 “아, 값이 3개니까 방을 3개 만들면 되겠구나!”라고 스스로 판단하게 하는 방법입니다.

int scores[] = {100, 95, 90}; // 컴퓨터가 자동으로 크기를 3으로 설정합니다.
  • [ ] 안을 비워두면 우측의 초기화 값 개수에 따라 크기가 결정됩니다. 아주 편리하죠?

2. 배열의 핵심: “0부터 시작하는 인덱스”

여기서 초보자분들이 가장 많이 멘붕 오는 포인트가 나옵니다. C 언어의 배열 인덱스는 1이 아니라 0부터 시작합니다.

재준봇의 꿀팁: 왜 0부터 시작하냐고요? 컴퓨터 입장에서 인덱스는 “시작 지점에서 얼마나 떨어져 있는가(Offset)”를 의미하기 때문입니다. 첫 번째 방은 시작 지점에서 0만큼 떨어져 있으니 0번 방이 되는 거죠. 이거 헷갈려서 1번부터 넣다가 프로그램 터지는 경우 정말 많습니다. 주의하세요!

실전 코드 예제 1: 배열의 값 바꾸고 출력하기

#include <stdio.h>

int main() {
    // 1. 정수형 배열 선언 및 초기화
    int myNumbers[3] = {10, 20, 30};

    // 2. 첫 번째 요소(0번 인덱스)의 값을 100으로 변경
    myNumbers[0] = 100; 

    // 3. 각 요소의 값을 출력
    printf("첫 번째 방: %d\n", myNumbers[0]); // 100 출력
    printf("두 번째 방: %d\n", myNumbers[1]); // 20 출력
    printf("세 번째 방: %d\n", myNumbers[2]); // 30 출력

    return 0;
}

코드 뜯어보기:

  • int myNumbers[3] = {10, 20, 30};: 정수 3개가 들어가는 배열을 만들고 값을 채웠습니다.
  • myNumbers[0] = 100;: myNumbers라는 아파트의 0번 방에 있던 10을 빼고 100을 넣었습니다.
  • printf("%d", myNumbers[0]);: 0번 방에 저장된 값을 꺼내서 화면에 보여줍니다.

3. 문자열(String): “문자들의 기차 놀이”

C 언어에는 다른 언어(Python, Java 등)와 달리 String이라는 기본 자료형이 없습니다. 대신 char형 배열을 사용해 문자열을 표현합니다.

문자열은 단순한 문자 배열이 아니라, 끝에 반드시 널 문자(\0)라는 특수한 표시가 붙어 있어야 합니다. 이게 없으면 컴퓨터는 문자열이 어디서 끝나는지 몰라서 메모리의 엉뚱한 곳까지 계속 읽다가 프로그램이 죽어버립니다.

문자열을 만드는 3가지 방법

방법 1: 문자열 리터럴 사용하기 (가장 추천)

큰따옴표("")를 사용하면 컴파일러가 자동으로 끝에 \0을 붙여줍니다.

char name[10] = "Jaejun"; 
  • name 배열의 크기는 10이지만, 실제 들어간 글자는 J, a, e, j, u, n 그리고 \0 까지 총 7개입니다. 남은 3칸은 비어있게 됩니다.

방법 2: 문자 하나하나 직접 넣기 (노가다 방식)

중괄호를 사용해 문자 하나하나를 넣는 방식입니다. 이때는 \0을 반드시 직접 써줘야 합니다.

char name[] = {'J', 'a', 'e', 'j', 'u', 'n', '\0'};
  • 이렇게 안 하면 이건 그냥 ‘문자 배열’이지 ‘문자열’이 아닙니다. \0을 빼먹는 순간 대재앙이 시작됩니다.

방법 3: 포인터를 이용한 선언 (심화)

배열 크기를 지정하지 않고 문자열 상수를 가리키게 하는 방식입니다.

char *name = "Jaejun";
  • 이 방식은 읽기 전용 메모리에 저장되기 때문에 내용을 수정할 수 없다는 특징이 있습니다. 나중에 포인터 강좌에서 자세히 다룰게요!

4. 반복문과 배열의 찰떡궁합: “한 번에 싹 다 처리하기”

배열을 배우는 진짜 이유는 반복문과 함께 쓰기 위해서입니다. 배열의 인덱스가 숫자이기 때문에, 반복문의 제어 변수(i)를 인덱스로 사용하면 수천 개의 데이터도 단 몇 줄로 처리할 수 있습니다.

실전 코드 예제 2: 세 가지 반복문으로 배열 합계 구하기

이 예제에서는 for, while, do-while 문을 각각 사용하여 배열의 모든 합계를 구하는 방법을 보여드리겠습니다. 결과는 모두 같지만 스타일이 다릅니다!

#include <stdio.h>

int main() {
    int scores[5] = {85, 90, 78, 92, 88};
    int sum = 0;
    int i;

    // 방법 1: for 문 (가장 정석적인 방법)
    // 반복 횟수가 정해져 있을 때 사용합니다.
    for (i = 0; i < 5; i++) {
        sum += scores[i];
    }
    printf("for문 합계: %d\n", sum);

    // 합계 초기화
    sum = 0;

    // 방법 2: while 문 (조건이 만족될 때까지)
    // 인덱스 변수를 직접 관리해야 합니다.
    i = 0;
    while (i < 5) {
        sum += scores[i];
        i++;
    }
    printf("while문 합계: %d\n", sum);

    // 합계 초기화
    sum = 0;

    // 방법 3: do-while 문 (일단 한 번은 실행하고 시작)
    // 조건 검사를 나중에 합니다.
    i = 0;
    do {
        sum += scores[i];
        i++;
    } while (i < 5);
    printf("do-while문 합계: %d\n", sum);

    return 0;
}

코드 뜯어보기:

  • sum += scores[i];: scores[0]부터 scores[4]까지 차례대로 sum 변수에 더해줍니다.
  • for 문: 초기식, 조건식, 증감식이 한 줄에 있어 가독성이 가장 좋습니다.
  • while 문: i = 0을 먼저 선언하고, 루프 안에서 i++를 통해 인덱스를 증가시킵니다.
  • do-while 문: 일단 do 블록을 실행한 뒤 while 조건문을 확인합니다. 배열이 비어있지 않을 때 유용합니다.

5. 특별 코너

❓ 초보자 폭풍 질문!

Q: “선생님! 배열 크기를 5로 만들었는데 scores[5]에 값을 넣으면 어떻게 되나요? 6번째 방이니까 가능할 것 같은데요?”

A: (정색하며) 절대 안 됩니다! 여러분, 인덱스가 0부터 시작한다고 했죠? 크기가 5인 배열의 인덱스는 0, 1, 2, 3, 4까지입니다. scores[5]는 6번째 방을 의미하는데, 우리는 방을 5개밖에 안 만들었습니다. 남의 집 담장을 넘는 격이죠! 이렇게 되면 ‘배열 범위 초과(Buffer Overflow)’라는 오류가 발생하며 프로그램이 갑자기 종료되거나, 메모리의 엉뚱한 값을 읽어와서 이상한 결과가 나옵니다. C 언어는 친절하게 “너 범위를 벗어났어!”라고 알려주지 않고 그냥 죽어버리는 경우가 많으니 정말 조심해야 합니다.

⚠️ 실무주의보

실무에서는 배열의 크기를 상수로 관리하세요!

코드 여기저기에 5라는 숫자를 직접 적어 넣으면, 나중에 배열 크기를 10으로 바꿀 때 모든 숫자를 찾아서 수정해야 합니다. 이때 실수로 하나라도 안 바꾸면 버그가 터집니다.

나쁜 예: for (i = 0; i < 5; i++) 좋은 예:

#define MAX_SIZE 5
// ...
for (i = 0; i < MAX_SIZE; i++)

이렇게 #define을 사용해 이름을 붙여주면, 나중에 MAX_SIZE 값 하나만 바꾸면 프로그램 전체에 적용됩니다. 실무에서는 필수 중의 필수입니다!


마무리하며

오늘 우리는 데이터를 묶어서 관리하는 배열과, 문자의 배열인 문자열에 대해 깊게 알아봤습니다.

  • 배열은 0번 방부터 시작한다!
  • 문자열 끝에는 반드시 \0 (널 문자)가 있어야 한다!
  • 반복문과 함께 쓰면 수천 개의 데이터도 순식간에 처리할 수 있다!

이 세 가지만 기억해도 여러분은 오늘 C 언어의 큰 산 하나를 넘으신 겁니다. 처음엔 인덱스 0번이 낯설고 \0이 귀찮겠지만, 계속 연습하다 보면 어느새 익숙해지실 거예요.

다음 시간에는 이 배열과 문자열을 더 강력하게 다룰 수 있는 ‘포인터’라는 최종 보스를 만나러 가겠습니다. 다들 마음의 준비 단단히 하시고, 오늘 배운 내용은 꼭 직접 코드로 쳐보시길 바랍니다. 고생하셨습니다!



<hr>

💬 궁금한 점이 있다면 자유롭게 댓글을 남겨주세요! (AI 비서가 답변해 드립니다 🤖)

Categories:

Updated: