프로그래밍 강좌/C언어

C언어란? gcc·clang 설치와 Hello World 컴파일·실행 | C언어 강좌 1강

IIRN 2026. 11. 8. 20:01
C언어의 특징과 쓰임새를 살펴보고, gcc·clang 컴파일러를 설치해 첫 Hello World 프로그램을 만들어 봅니다. 소스 코드가 실행 파일이 되기까지의 전처리·컴파일·어셈블·링크 과정도 함께 정리합니다.

이번 강에서는 C언어가 어떤 언어인지 살펴보고, 컴파일러를 설치해 첫 프로그램인 Hello World를 직접 실행해 봐요. 코드를 쓰는 것만큼 중요한 것이 그 코드가 어떻게 실행 파일로 바뀌는지 아는 것이에요.

이 과정을 처음에 이해해 두면 앞으로 만날 오류 메시지도 훨씬 쉽게 읽을 수 있어요.

C언어는 어떤 언어인가요

C언어는 1972년 무렵 벨 연구소의 데니스 리치가 유닉스 운영체제를 만들기 위해 설계한 언어예요. 50년이 넘었지만 지금도 꾸준히 표준이 갱신되고 있고, 가장 최신 표준은 C23이에요.

C는 '고급 언어'이면서도 하드웨어에 아주 가까운 수준까지 다룰 수 있어요. 그래서 흔히 '이식성 있는 어셈블리'라고 부르기도 해요.

C의 주요 특징

특징 설명
빠른 실행 속도 기계어로 직접 번역되어 실행되므로 군더더기가 거의 없어요
메모리를 직접 다룸 포인터로 메모리 주소를 직접 읽고 쓸 수 있어요(나중에 배웁니다)
작고 단순한 문법 키워드 수가 적고, 언어 자체가 제공하는 기능이 최소한이에요
높은 이식성 거의 모든 CPU와 운영체제에 C 컴파일러가 있어요
컴파일 언어 실행 전에 소스 코드를 실행 파일로 미리 번역해야 해요

장점만 있는 것은 아니에요. 메모리를 직접 다루는 만큼 실수하면 프로그램이 갑자기 종료되거나 보안 문제가 생길 수 있어서, 꼼꼼하게 코드를 작성하는 습관이 필요해요.

C는 어디에 쓰이나요

  • 운영체제: 리눅스 커널, 윈도우와 macOS의 핵심 부분이 C로 작성되어 있어요.
  • 임베디드 시스템: 세탁기, 자동차 제어 장치, 마이크로컨트롤러처럼 자원이 적은 기기에서 많이 써요.
  • 다른 언어의 기반: 파이썬의 기본 구현(CPython)이 C로 만들어져 있어요.
  • 데이터베이스·네트워크: SQLite, Redis, Nginx 같은 고성능 소프트웨어가 C로 작성되었어요.

C++, Java, C#, JavaScript 같은 많은 언어가 C의 문법을 물려받았어요. 그래서 C를 익혀 두면 다른 언어를 배울 때도 문법이 낯설지 않아요.

컴파일러가 필요한 이유

컴퓨터의 CPU는 0과 1로 된 기계어만 이해해요. 사람이 쓴 C 코드(소스 코드)를 기계어로 번역해 주는 프로그램이 바로 컴파일러예요.

C 컴파일러로 가장 많이 쓰는 것은 gcc(GNU Compiler Collection)와 clang(LLVM 프로젝트)이에요. 둘 다 무료이고 사용법도 거의 같아서, 이 강좌의 명령어는 gcc 자리에 clang을 넣어도 그대로 동작해요.

개발 환경 준비하기

운영체제별로 컴파일러를 설치하는 방법이 달라요. 자신의 환경에 맞는 부분만 따라 하면 돼요.

Windows

Windows에서는 MSYS2를 이용해 gcc를 설치하는 방법이 간편해요. msys2.org에서 설치 프로그램을 내려받아 설치한 뒤, 'MSYS2 UCRT64' 터미널을 열고 다음 명령을 입력하세요.

pacman -S mingw-w64-ucrt-x86_64-gcc

설치 후 C:\msys64\ucrt64\bin 폴더를 환경 변수 Path에 추가하면 일반 명령 프롬프트나 PowerShell에서도 gcc를 쓸 수 있어요. 리눅스 환경이 익숙하다면 WSL(Windows Subsystem for Linux)을 설치한 뒤 아래 리눅스 방법을 따라도 좋아요.

macOS

macOS에서는 터미널에 다음 한 줄만 입력하면 Apple이 제공하는 clang이 설치돼요.

xcode-select --install

macOS에서는 gcc라고 입력해도 실제로는 clang이 실행돼요. 사용법이 같으니 신경 쓰지 않아도 괜찮아요.

Linux (Ubuntu·Debian 계열)

sudo apt update
sudo apt install build-essential

build-essential 패키지에 gcc와 함께 기본 개발 도구가 모두 들어 있어요. clang을 쓰고 싶다면 sudo apt install clang으로 따로 설치하면 돼요.

설치 확인

어느 운영체제든 터미널에서 버전을 확인해 보세요.

gcc --version

버전 정보가 출력되면 설치가 끝난 거예요. command not found나 'gcc'은(는) 내부 또는 외부 명령...이 아닙니다 같은 메시지가 나오면 설치가 덜 되었거나 Path 설정이 빠진 것이에요.

코드 편집기는 Visual Studio Code처럼 가벼운 편집기면 충분해요. 처음에는 편집기에서 파일을 저장하고 터미널에서 직접 컴파일하는 방식을 권해요.

그래야 컴파일 과정이 눈에 보여요.

첫 프로그램: Hello World

편집기에서 새 파일을 만들고 이름을 hello.c로 저장하세요. C 소스 파일은 확장자가 반드시 .c여야 해요.

#include <stdio.h>  // 화면 출력 기능(printf)을 쓰기 위한 준비

int main(void)      // 프로그램이 시작되는 곳
{
    printf("Hello, World!\n");  // 화면에 문장을 출력
    return 0;                    // 프로그램이 정상 종료되었음을 알림
}

컴파일하고 실행하기

파일을 저장한 폴더로 이동한 뒤 다음 명령을 입력하세요.

gcc hello.c -o hello
./hello

Windows 명령 프롬프트라면 실행 파일 이름이 hello.exe가 되고, 실행할 때는 hello만 입력하면 돼요.

Hello, World!

코드 해설

  • #include <stdio.h>: 표준 입출력 기능을 가져오는 줄이에요. printf를 쓰려면 꼭 필요해요.
  • int main(void): 모든 C 프로그램은 main에서 실행을 시작해요.
  • printf("..."): 큰따옴표 안의 글자를 화면에 출력해요. \n은 줄을 바꾸라는 뜻이에요.
  • return 0;: 프로그램이 문제없이 끝났다는 신호를 운영체제에 돌려줘요.
  • 문장 끝의 ;(세미콜론)은 '여기서 한 문장이 끝난다'는 표시예요.

각 줄이 왜 이런 모양인지는 2강 'C 프로그램의 구조'에서 자세히 다루고, printf의 다양한 사용법은 4강에서 배워요. 지금은 '이렇게 쓰면 출력된다' 정도로만 받아들이면 충분해요.

명령어 해설

gcc hello.c -o hello는 'hello.c를 컴파일해서 hello라는 이름의 실행 파일을 만들어라'라는 뜻이에요. -o 옵션을 빼면 실행 파일 이름이 a.out(Windows는 a.exe)으로 정해져요.

./hello의 ./는 '현재 폴더에 있는'이라는 뜻이에요. 리눅스와 macOS에서는 보안상 현재 폴더의 프로그램을 실행할 때 이 경로를 붙여야 해요.

여러 줄 출력해 보기

printf를 여러 번 쓰면 여러 줄을 출력할 수 있어요. 파일 이름은 intro.c로 해 볼게요.

#include <stdio.h>

int main(void)
{
    printf("안녕하세요!\n");
    printf("C언어 공부를 시작합니다.\n");
    printf("오늘의 목표: 첫 프로그램 실행하기\n");
    return 0;
}
gcc intro.c -o intro
./intro
안녕하세요!
C언어 공부를 시작합니다.
오늘의 목표: 첫 프로그램 실행하기

문장은 위에서 아래로 순서대로 실행돼요. 각 printf 끝에 \n이 있어서 한 줄씩 나뉘어 출력돼요.

Windows 명령 프롬프트에서 한글이 깨져 보인다면 소스 파일을 UTF-8로 저장하고, 실행 전에 chcp 65001을 입력해 터미널을 UTF-8 모드로 바꿔 보세요.

줄바꿈을 빼먹으면

\n이 없으면 다음 출력이 같은 줄에 바로 이어 붙어요.

#include <stdio.h>

int main(void)
{
    printf("사과");        // 줄바꿈 없음
    printf("바나나\n");    // 여기서 줄바꿈
    printf("포도\n");
    return 0;
}
사과바나나
포도

printf는 알아서 줄을 바꿔 주지 않아요. 줄을 바꾸고 싶은 곳에 직접 \n을 넣어야 해요.

컴파일과 실행 과정

gcc hello.c -o hello 한 줄은 사실 네 단계를 한꺼번에 처리해요. 각 단계를 알아 두면 오류가 어느 단계에서 났는지 구분할 수 있어요.

단계 하는 일 결과물 그 단계에서 멈추는 옵션
전처리 #include 같은 # 명령을 처리해 헤더 내용을 붙여 넣음 hello.i -E
컴파일 C 코드를 어셈블리어로 번역 hello.s -S
어셈블 어셈블리어를 기계어로 바꿔 목적 파일 생성 hello.o -c
링크 목적 파일과 라이브러리(printf 구현 등)를 합쳐 실행 파일 생성 hello (옵션 없음)

단계별로 직접 확인하기

각 단계를 하나씩 실행해 볼 수도 있어요.

gcc -E hello.c -o hello.i   # 1. 전처리만
gcc -S hello.i -o hello.s   # 2. 어셈블리어로 번역
gcc -c hello.s -o hello.o   # 3. 목적 파일 생성
gcc hello.o -o hello        # 4. 링크해서 실행 파일 생성
./hello
Hello, World!

hello.i를 열어 보면 몇 줄짜리 코드가 수백 줄로 늘어나 있어요. #include <stdio.h>가 그 자리에 stdio.h의 내용을 통째로 붙여 넣었기 때문이에요.

hello.s에는 CPU 명령어가 사람이 읽을 수 있는 형태로 적혀 있어요. hello.o는 기계어라서 편집기로 열면 알아볼 수 없는 글자가 보여요.

컴파일 오류와 링크 오류

오류 메시지에 error:와 함께 파일 이름과 줄 번호가 나오면 대부분 컴파일 단계의 문법 오류예요. 반면 undefined reference to ...처럼 나오면 링크 단계에서 함수의 실제 구현을 찾지 못했다는 뜻이에요.

경고 옵션을 켜는 습관

컴파일할 때 -Wall -Wextra를 붙이면 컴파일러가 의심스러운 코드를 경고로 알려 줘요. 처음부터 이 옵션을 습관처럼 쓰는 것을 권해요.

gcc -Wall -Wextra hello.c -o hello

특정 표준을 지정하고 싶다면 -std=c17이나 -std=c23을 붙여요. 최신 gcc는 옵션이 없으면 C23 기반 모드로 컴파일해요.

소스를 고치면 다시 컴파일

실행 파일은 컴파일한 그 순간의 소스 코드로 만들어진 결과물이에요. 소스를 수정한 뒤 컴파일하지 않고 실행하면 예전 내용이 그대로 출력돼요.

자주 하는 실수

세미콜론 빠뜨리기

가장 흔한 실수예요. printf 줄 끝에 ;를 빼면 이런 오류가 나요.

    printf("Hello, World!\n")
    return 0;
hello.c: In function 'main':
hello.c:5:30: error: expected ';' before 'return'

hello.c:5:30은 5번째 줄 30번째 칸이라는 뜻이에요. 오류가 표시된 줄의 바로 앞줄에 실제 원인이 있는 경우가 많으니 함께 살펴보세요.

대소문자 틀리기

C는 대문자와 소문자를 구분해요. Printf나 Main으로 쓰면 전혀 다른 이름으로 취급돼요.

hello.c:5:5: error: implicit declaration of function 'Printf'; did you mean 'printf'? [-Wimplicit-function-declaration]

컴파일러가 did you mean 'printf'?라고 친절하게 힌트를 주기도 해요. 오류 메시지를 끝까지 읽는 습관을 들이세요.

그 밖의 주의할 점

  • 파일을 hello.c.txt처럼 저장하면 컴파일러가 파일을 찾지 못해요. 확장자를 꼭 확인하세요.
  • 따옴표는 반드시 영문 큰따옴표 "를 써야 해요. 워드 프로세서에서 복사한 “ ” 모양 따옴표는 오류가 나요.
  • 리눅스·macOS에서 hello만 입력하면 command not found가 나와요. ./hello로 실행하세요.

연습 문제

  1. 다음 모양을 그대로 출력하는 프로그램 box.c를 작성하고 컴파일해 실행해 보세요.
*****
* C *
*****
  1. 다음 코드에는 오류가 두 개 있어요. 찾아서 고친 뒤 Fixed!가 출력되게 만들어 보세요.
#include <stdio.h>

int main(void)
{
    Printf("Fixed!\n")
    return 0;
}
  1. greet.c를 경고 옵션 -Wall -Wextra를 켜고 컴파일해서 실행 파일 이름을 greet로 만드는 명령과, 그 파일을 리눅스에서 실행하는 명령을 써 보세요.

정답 예시

1번

#include <stdio.h>

int main(void)
{
    printf("*****\n");
    printf("* C *\n");
    printf("*****\n");
    return 0;
}
*****
* C *
*****

한 줄마다 printf를 하나씩 쓰고, 끝에 \n을 붙여 줄을 바꿔요.

2번

#include <stdio.h>

int main(void)
{
    printf("Fixed!\n");  // Printf → printf, 끝에 세미콜론 추가
    return 0;
}
Fixed!

첫 번째 오류는 대문자 P, 두 번째 오류는 빠진 세미콜론이에요.

3번

gcc -Wall -Wextra greet.c -o greet
./greet

옵션의 순서는 바뀌어도 괜찮지만, -o 바로 뒤에는 반드시 만들 실행 파일 이름이 와야 해요.

핵심 정리

  • C는 1972년에 탄생한 컴파일 언어로, 빠르고 하드웨어에 가까우며 운영체제·임베디드·고성능 소프트웨어에 널리 쓰여요.
  • 대표 컴파일러는 gcc와 clang이며, 사용법이 거의 같아요.
  • 설치 방법: Windows는 MSYS2(또는 WSL), macOS는 xcode-select --install, 리눅스는 build-essential이에요.
  • gcc 파일.c -o 이름으로 컴파일하고 ./이름으로 실행해요.
  • 컴파일은 전처리(-E) → 컴파일(-S) → 어셈블(-c) → 링크 네 단계로 이루어져요.
  • printf는 자동으로 줄을 바꾸지 않으니 \n을 직접 넣어야 해요.
  • 세미콜론 누락과 대소문자 실수가 가장 흔한 오류이고, 오류 메시지의 줄 번호와 힌트를 끝까지 읽는 것이 해결의 시작이에요.
  • -Wall -Wextra 옵션을 켜고 컴파일하는 습관을 들이세요.

강좌 이어 보기