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