[C 01] C란 무엇인가, 첫 프로그램 만들기

이 글은 코딩을 한 번도 해 본 적 없는 분을 위한 C 언어 첫걸음입니다. C가 어떤 언어이고 왜 배우는지부터, 화면에 글자 한 줄을 찍는 프로그램을 직접 만들어 컴파일하고 실행하는 데까지 따라가 봅니다. 나오는 용어는 처음 등장할 때마다 풀어서 설명하니, 순서대로 천천히 읽으시면 됩니다.

01.1 C라는 언어

C(씨)는 1970년대 초에 만들어진 프로그래밍 언어입니다. 프로그래밍 언어란 사람이 컴퓨터에게 시킬 일을 적어 두기 위한, 서로 약속된 문법을 말합니다. 컴퓨터는 사람 말을 그대로 알아듣지 못하기 때문에, 정해진 규칙대로 명령을 써 줘야 그대로 실행합니다.

C를 배우는 이유는 분명합니다. 우리가 쓰는 운영체제(윈도우, 리눅스처럼 컴퓨터를 움직이는 기본 소프트웨어)나 가전제품 속 작은 컴퓨터, 그리고 파이썬, 자바 같은 다른 언어들 상당수가 C로 만들어졌거나 C의 문법을 물려받았습니다. 또 C는 메모리(데이터를 잠깐 저장해 두는 컴퓨터 부품)를 직접 다루기 때문에, 컴퓨터가 실제로 어떻게 움직이는지를 가장 가까이에서 배울 수 있습니다. C를 익혀 두면 다른 언어로 넘어가기가 훨씬 수월합니다.

01.2 소스 코드, 컴파일, 실행 파일

C로 프로그램을 만들려면 세 가지 개념을 먼저 알아야 합니다. 첫째, 소스 코드(source code)는 사람이 읽고 쓰는 글자로 된 프로그램입니다. 우리가 앞으로 손으로 적는 것이 바로 이 소스 코드이며, 보통 이름 뒤에 .c가 붙는 파일에 저장합니다.

둘째, 컴파일(compile)은 이 소스 코드를 컴퓨터가 실제로 실행할 수 있는 형태로 번역하는 과정입니다. 번역을 해 주는 프로그램을 컴파일러(compiler)라고 부릅니다. 사람이 쓴 글자를 컴퓨터가 바로 알아듣지는 못하므로, 중간에서 번역기가 한 번 바꿔 주는 것입니다.

셋째, 실행 파일(executable)은 컴파일이 끝나 실제로 돌릴 수 있게 된 결과물입니다. C는 이렇게 컴파일이라는 번역 단계를 거치는 언어라서, 코드를 고칠 때마다 다시 컴파일해서 새 실행 파일을 만들어야 합니다. 이 흐름을 정리하면 다음과 같습니다.


hello.c (소스 코드) --컴파일--> hello (실행 파일) --실행--> 화면 출력


01.3 준비물과 컴파일 명령

실습에는 컴파일러가 하나 필요합니다. 가장 널리 쓰이는 것은 gcc(지씨씨)라는 무료 컴파일러입니다. 리눅스나 맥에는 이미 있거나 쉽게 설치되고, 윈도우에서는 MinGW(민지더블유)나 WSL(윈도우에서 리눅스를 쓰게 해 주는 기능)을 통해 gcc를 준비할 수 있습니다.

준비가 되면 순서는 늘 같습니다. 먼저 소스 코드를 hello.c라는 이름으로 저장합니다. 그다음 터미널(명령을 글자로 입력하는 검은 창)에서 아래 두 줄을 차례로 칩니다.


gcc hello.c -o hello
./hello


첫 줄은 "hello.c를 컴파일해서 hello라는 이름의 실행 파일로 만들어라"라는 뜻입니다. 여기서 -o는 만들 실행 파일의 이름을 정해 주는 표시입니다. 둘째 줄 ./hello는 방금 만든 실행 파일을 실제로 돌리라는 명령입니다. 윈도우 명령 창에서는 ./hello 대신 hello.exe처럼 실행하기도 합니다.

01.4 첫 프로그램, 화면에 인사말 출력

이제 가장 유명한 첫 프로그램을 만들어 봅니다. 화면에 Hello, World! 한 줄을 찍는 프로그램입니다. 아래 내용을 그대로 hello.c에 옮겨 적어 보세요.


#include <stdio.h>

int main(void) {
printf("Hello, World!\n");
return 0;
}


앞서 배운 대로 gcc hello.c -o hello로 컴파일하고 ./hello로 실행하면, 화면에는 이렇게 나옵니다.


Hello, World!


글자 몇 개지만, 소스 코드를 쓰고 컴파일하고 실행하는 C의 한 사이클을 방금 전부 경험한 것입니다.

01.5 프로그램을 한 줄씩 뜯어보기

짧은 코드지만 새 용어가 여럿 들어 있습니다. 하나씩 풀어 보겠습니다.

첫 줄 #include <stdio.h>는 준비 작업입니다. stdio.h는 화면 출력·키보드 입력과 관련된 기능이 모여 있는 헤더(header, 미리 만들어진 기능 묶음) 파일이고, #include는 그 묶음을 이 프로그램에 끌어와 쓰겠다는 선언입니다. 뒤에 나올 printf가 이 안에 들어 있어서, 이 줄이 없으면 출력을 못 합니다.

int main(void) { ... }는 main 함수입니다. 함수(function)란 어떤 일을 하는 명령들을 하나로 묶어 이름 붙인 덩어리를 말합니다. 그중 main은 특별해서, 모든 C 프로그램은 반드시 main에서 실행을 시작합니다. 중괄호 { } 안에 적힌 명령들이 위에서 아래로 순서대로 실행됩니다.

printf("Hello, World!\n");가 실제로 화면에 글자를 찍는 부분입니다. printf는 큰따옴표 " " 사이에 적은 문자열(글자들의 나열)을 화면에 출력하는 기능입니다. 끝의 \n은 줄바꿈을 뜻하는 특별한 신호로, 화면에 \n이라는 글자가 찍히는 게 아니라 커서가 다음 줄로 내려갑니다.

return 0;은 프로그램을 정상적으로 마쳤다고 알리는 표시입니다. 여기서 숫자 0은 "문제없이 끝났다"는 관례적인 신호입니다.

마지막으로 printf(...)return 0 줄 끝에 붙은 세미콜론 ;을 눈여겨보세요. C에서는 명령 하나가 끝날 때마다 세미콜론을 찍어 문장의 끝을 표시합니다. 주의. 이 세미콜론을 빠뜨리면 컴파일이 실패하니, 초보 때 가장 자주 만나는 실수입니다.

01.6 여러 줄 출력하기

이번에는 자기소개를 세 줄로 찍어 봅니다. printf를 여러 번 부르면 부른 순서 그대로 실행됩니다.


#include <stdio.h>

int main(void) {
printf("이름: 홍길동\n");
printf("나이: 20\n");
printf("취미: 코딩\n");
return 0;
}


실행하면 세 줄이 차례로 나옵니다.


이름: 홍길동
나이: 20
취미: 코딩


printf 끝의 \n 덕분에 한 줄씩 내려가며 찍힙니다. 줄바꿈은 자동으로 되는 것이 아니라, 이렇게 내가 직접 넣어 줘야 한다는 점이 핵심입니다.

01.7 한 줄에 이어 붙이기

그렇다면 \n을 빼면 어떻게 될까요. 다음처럼 \n 없이 세 번 출력해 봅니다.


#include <stdio.h>

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


결과는 세 글자가 한 줄에 딱 붙어 나옵니다.


ABC


\n이 없으면 다음 출력이 앞 출력 뒤에 그대로 이어집니다. 줄을 나누고 싶은 자리에만 \n을 넣으면 된다는 뜻입니다. 마지막 printf에만 \n을 붙여 줄을 마무리한 것도 눈여겨보세요.

01.8 따옴표와 역슬래시 출력

화면에 큰따옴표(")나 역슬래시(\) 같은 글자 자체를 찍고 싶을 때가 있습니다. 그런데 큰따옴표는 문자열의 시작과 끝을 나타내는 데 이미 쓰이고, 역슬래시는 \n처럼 특별한 신호의 앞머리로 쓰입니다. 그래서 이 글자들은 앞에 역슬래시를 하나 더 붙여 표시합니다. 이것을 이스케이프(escape)라고 합니다.


#include <stdio.h>

int main(void) {
printf("그는 \"안녕\"이라고 말했다.\n");
printf("경로: C:\\Users\\test\n");
return 0;
}


실행 결과는 다음과 같습니다.


그는 "안녕"이라고 말했다.
경로: C:\Users\test


\"는 큰따옴표 한 개를, \\는 역슬래시 한 개를 화면에 찍습니다. 함정. 경로를 적을 때 역슬래시를 하나만 쓰면, 컴파일러가 뒤 글자와 묶어 다른 신호로 해석하거나 경고를 내니, 역슬래시 자체를 찍을 때는 반드시 두 개로 씁니다.

01.9 처음에 자주 만나는 오류

초보 단계에서 컴파일이 안 될 때는 대부분 사소한 실수입니다. 세 가지만 기억해 두시면 됩니다. 첫째, 문장 끝 세미콜론 ;을 빠뜨리지 않았는지 봅니다. 둘째, 문자열의 큰따옴표 " "를 한쪽만 적지 않았는지, 그리고 여는 중괄호 {와 닫는 중괄호 }의 개수가 맞는지 확인합니다. 셋째, Printf처럼 대문자로 잘못 쓰지 않았는지 봅니다. C는 대문자와 소문자를 다른 글자로 구분하므로, printf는 반드시 소문자로 적어야 합니다.

여기까지 왔다면 소스 코드를 작성하고, 컴파일하고, 실행해 결과를 확인하는 과정을 온전히 해낸 것입니다. 화면에 원하는 글자를 마음대로 찍을 수 있게 되었으니, C로 무언가를 만들기 위한 첫 도구를 손에 쥔 셈입니다.