많은 사람이 C 언어를 처음 접하면 “좀 딱딱하다”고 느낍니다. 편리한 캡슐화도 적고, 문법 설탕도 많지 않아 많은 것을 직접 써야 합니다. 하지만 그래서 C는 기초를 다지기에 아주 좋습니다.
C는 당신에게 이런 것들을 피하지 못하게 합니다.
변수는 무엇인지, 입력에서 왜 주소를 넘기는지, 배열과 반복문이 왜 찰떡인지, 함수 인자는 어떻게 전달되는지, 그리고 포인터가 왜 계속 등장하는지.
이 기본을 제대로 이해하면, 이후 C++/Java/Python을 배우거나 운영체제/임베디드/자료구조를 접할 때도 이해가 훨씬 단단해집니다. 이 글은 초보자가 가장 자연스럽게 인지 구조를 만들 수 있는 순서로 C의 핵심을 묶어 전체 지식 프레임을 세우는 데 목적이 있습니다.
1. C를 배울 때 잡아야 할 3가지 축
초반에 흔히 하는 실수는 C를 “단어 암기”처럼 배우는 것입니다. if를 외우고 for를 외우고 scanf를 외우다 보면 머릿속이 산만해집니다.
더 좋은 방법은 세 가지 축을 먼저 잡는 것입니다.
1) 데이터는 어떻게 저장되는가
변수, 배열, 구조체, 문자열은 모두 “정보를 어디에 담는가”를 다룹니다.
2) 프로그램은 어떻게 흐름을 제어하는가
순차, 분기, 반복은 “일을 어떤 순서로 수행하는가”를 다룹니다.
3) 프로그램은 데이터를 어떻게 찾아오는가
이는 scanf, 함수 인자 전달, 배열, 포인터, 파일 I/O까지 이어집니다.
이 축을 따라가면 지식이 자연스럽게 연결됩니다.
2. 변수: 프로그램이 데이터를 “기억”하는 방법
예:
int age = 18;age라는 정수 변수를 만들고 18을 넣었다는 뜻입니다. 여기서 반드시 이해해야 할 것은 식별자와 자료형입니다.
2.1 식별자: 데이터에 이름 붙이기
변수/함수/배열 이름은 식별자입니다.
- 영문자, 숫자, 밑줄 사용
- 숫자로 시작 불가
- 키워드 사용 불가
- 대소문자 구분
2.2 자료형: 변수에 무엇을 담을 수 있나
int a = 10;
float b = 3.14;
char c = 'A';C에서는 변수마다 “이 상자에 무엇을 담는가”가 정해져 있습니다. 이후 입력/출력/연산/메모리 이해에 큰 영향을 줍니다.
3. 입출력: 프로그램이 사람과 상호작용하는 법
3.1 출력: printf
printf("Hello C!\n");변수 출력은 포맷 지정자가 필요합니다.
%d정수%f실수%c문자%s문자열
핵심은 “프로그램이 데이터를 어떤 타입으로 해석해 출력해야 하는지 알아야 한다”입니다.
3.2 입력: scanf와 &의 의미
int age;
scanf("%d", &age);scanf는 값을 읽는 것이 아니라 변수가 있는 메모리 위치에 값을 써야 하므로 주소가 필요합니다.
age: 값&age: 주소
여기서부터 C의 핵심인 “값뿐 아니라 위치(주소)도 다룬다”가 시작됩니다.
4. 연산자와 표현식
산술 연산자:
+ - * / %정수 나눗셈은 소수부가 버려지고, %는 정수에서만 사용합니다.
복합 대입:
a += 3;
a -= 3;논리 연산:
!not&&and||or
5. 분기: 선택하기
5.1 if
if (x > 0) {
printf("양수\n");
} else {
printf("양수가 아님\n");
}5.2 else if로 구간 분기
if (score >= 90) printf("A");
else if (score >= 80) printf("B");
else if (score >= 70) printf("C");
else if (score >= 60) printf("D");
else printf("E");5.3 switch
switch (grade) {
case 'A':
printf("우수");
break;
default:
printf("기타");
}break를 빼면 아래로 이어 실행되는 “fall-through”가 발생합니다.
6. 반복: 같은 일을 여러 번
6.1 while
int i = 1;
while (i <= 5) {
printf("%d\n", i);
i++;
}6.2 do...while
int i = 1;
do {
printf("%d\n", i);
i++;
} while (i <= 5);6.3 for
for (int i = 1; i <= 5; i++) {
printf("%d\n", i);
}반복은 “문제를 반복 가능한 절차로 쪼개는 사고”입니다.
7. 함수: 기능을 분리해 재사용하기
int add(int a, int b) {
int c = a + b;
return c;
}함수는
- 복잡도를 낮추고
- 중복을 줄입니다.
값 전달 vs 주소 전달(포인터 전달)은 이후 포인터/배열 이해와 직결됩니다.
8. 배열: 동일 타입의 묶음
int arr[5] = {1, 2, 3, 4, 5};배열의 핵심 규칙:
- 인덱스는 0부터
- 배열과 반복문은 함께 쓰는 경우가 대부분
2차원 배열:
int arr[2][3] = {
{1, 2, 3},
{4, 5, 6}
};9. 포인터: C를 이해하는 관문
포인터는 주소를 저장하는 변수입니다.
int a = 10;
int *p = &a;p는a의 주소를 저장*p는 그 주소에 들어있는 값을 의미
2중 포인터:
int **pp = &p;배열 접근:
arr[2]
*(arr + 2)은 많은 경우 같은 의미입니다.
10. 구조체/문자열/전처리/파일
- 구조체: 여러 속성을 하나로 묶음
- 문자열: C에서 문자열은 “문자 배열 + 종료 문자
\0” #define: 컴파일 전 텍스트 치환- 파일:
FILE*,fopen, 읽기/쓰기 함수들
11. 한 장으로 정리
변수 → 입출력 → 연산 → 분기/반복 → 함수 → 배열 → 포인터 → 확장(구조체/문자열/파일)
이 순서를 따라가면 C는 “문법 암기”가 아니라 “컴퓨터가 어떻게 일하는가”를 이해하는 도구가 됩니다.
C가 어렵게 느껴지는 이유는 많은 것을 직접 다루기 때문이지만, 그만큼 기초를 단단히 세워줍니다.