프로그래밍 입문자는 먼저 코드가 어떤 과정을 거쳐 실행 파일이 되는지 알아야 합니다. C의 개발 환경은 단순해 보이지만, 전처리와 컴파일, 어셈블, 링킹의 경계를 이해하면 오류를 훨씬 빠르게 추적할 수 있습니다.
- 컴파일러 설치: GCC, Clang, MSVC 설치 및 환경 변수 설정
- IDE 세팅: VS Code, Visual Studio, CLion 등 활용법
- 컴파일 파이프라인: 전처리(Preprocessing) - 컴파일(Compilation) - 어셈블(Assembly) - 링킹(Linking) 과정 이해
c
#include <stdio.h>
int main(void) {
printf("Hello from C!\n");
return 0;
}
책처럼 천천히 이해하기
예상 시간: 읽기 10분 + 실습 15분. 처음 읽을 때는 전체를 외우려 하지 말고, 코드 한 줄이 어떤 원리와 연결되는지만 표시하면서 지나가세요.
왜 배우는가
- C는 운영체제 커널, 임베디드 펌웨어, 게임 엔진, 데이터베이스, 네트워크 서버처럼 하드웨어와 가까운 영역에서 오래 쓰인 언어입니다.
- 초보자가 C를 배우면 프로그램이 추상적인 버튼 클릭이 아니라 파일, 메모리, 기계어, 운영체제 호출의 조합이라는 사실을 일찍 이해하게 됩니다.
원리
- C 소스 파일은 곧바로 실행되지 않습니다. 사람이 읽는 텍스트가 전처리, 컴파일, 어셈블, 링킹 단계를 지나 CPU가 읽을 수 있는 실행 파일이 됩니다.
- 각 단계는 다른 종류의 오류를 만듭니다. 문법 오류는 보통 컴파일 단계, 함수 정의 누락은 링킹 단계, 0으로 나누기나 잘못된 주소 접근은 실행 중에 드러납니다.
- IDE는 이 과정을 감춰서 편하게 해 주는 도구일 뿐입니다. 실제 문제를 해결하려면 내부 파이프라인을 머릿속으로 따라갈 수 있어야 합니다.
비유로 붙잡기
요리로 비유하면 전처리는 흩어진 레시피와 재료 목록을 한 장으로 합치는 일, 컴파일은 레시피를 주방 기계가 이해할 작업 지시서로 바꾸는 일, 어셈블은 더 낮은 수준의 부품 지시서로 쪼개는 일, 링킹은 여러 부품과 이미 만들어진 도구를 볼트로 조여 완성품을 만드는 일입니다.
용어 풀이
- 소스 파일: 개발자가 작성한
.c,.cpp텍스트 파일입니다. - 전처리기:
#include,#define같은 지시문을 먼저 처리하는 도구입니다. - 컴파일러: C/C++ 문법을 검사하고 목적 파일을 만드는 프로그램입니다.
- 링커: 여러 목적 파일과 라이브러리를 묶어 실행 파일을 완성하는 도구입니다.
주석 달린 예제: 첫 C 프로그램을 줄 단위로 읽기
c
#include <stdio.h> // printf 선언이 들어 있는 표준 입출력 헤더를 포함합니다.
int main(void) { // 프로그램은 main 함수에서 시작합니다. void는 인자를 받지 않는다는 뜻입니다.
printf("Hello from C!\n"); // 화면에 문자열을 출력하고 \n으로 줄을 바꿉니다.
return 0; // 운영체제에 정상 종료를 알립니다. 0은 관례적으로 성공입니다.
}
실습과 오류 읽는 법
- 실습:
#include <stdio.h>를 지우고 분석합니다.- 예상 결과:
printf가 선언되지 않았다는 경고나 오류가 예상됩니다. - 읽는 법: 컴파일러가
printf라는 이름을 봤지만 함수의 모양을 모른다는 뜻입니다. 헤더는 함수 본문이 아니라 약속된 선언을 알려주는 표지판입니다.
- 예상 결과:
- 실습:
printf를printff로 바꿉니다.- 예상 결과: 컴파일은 지나가더라도 링킹 단계에서
undefined reference또는unresolved external류의 메시지가 날 수 있습니다. - 읽는 법: 문법상 함수 호출처럼 보이지만 실제 구현을 어디에서도 찾지 못했다는 뜻입니다. 이름 오타나 라이브러리 연결 누락을 먼저 확인합니다.
- 예상 결과: 컴파일은 지나가더라도 링킹 단계에서
자주 터지는 실수와 해결 습관
- Run 버튼만 누르지 말고 컴파일 명령과 오류 단계가 무엇인지 함께 봅니다. 메시지에
compile,link,runtime단서가 있는지 먼저 찾으세요. - 헤더는 구현이 아니라 선언 공유 장치입니다. 함수 본문이 어디에 있는지까지 확인해야 링킹 문제를 해결할 수 있습니다.
- 처음에는 경고도 오류처럼 다룹니다.
-Wall -Wextra로 경고를 켜고 메시지를 한 줄씩 읽는 습관이 가장 빨리 실력을 올립니다.
학습 목표
- 소스 파일이 전처리, 컴파일, 어셈블, 링킹을 거쳐 실행 파일이 되는 흐름을 말로 설명할 수 있다.
- GCC/Clang/MSVC 같은 컴파일러와 IDE가 실제로 담당하는 역할을 구분할 수 있다.
- 컴파일 오류, 링크 오류, 런타임 오류가 서로 다른 단계에서 발생한다는 점을 이해한다.
핵심 모델
C 개발 환경은 IDE가 아니라 컴파일 파이프라인이 중심입니다. IDE는 편집과 실행을 편하게 해주는 껍데기이고, 실제 프로그램은 전처리기가 헤더와 매크로를 펼친 뒤 컴파일러가 목적 파일을 만들고 링커가 여러 목적 파일과 라이브러리를 묶으면서 완성됩니다.
실습 순서
- `#include <stdio.h>`를 제거한 뒤 어떤 오류가 나는지 확인합니다.
- 함수 이름을 일부러 틀리게 작성해 컴파일 오류와 링크 오류의 차이를 관찰합니다.
- 컴파일러 경고 옵션을 켰을 때 어떤 문제가 미리 잡히는지 기록합니다.
- 같은 코드를 C와 C++ 모드에서 컴파일했을 때 메시지가 어떻게 달라지는지 비교합니다.
자주 터지는 실수
- IDE의 Run 버튼만 믿으면 실제 빌드 단계에서 무슨 일이 일어나는지 놓치기 쉽습니다.
- 헤더 파일은 구현이 아니라 선언을 공유하는 장치라는 점을 혼동하기 쉽습니다.
- 링크 오류는 문법이 맞아도 정의를 찾지 못하면 발생합니다.