Skip to main content

3. C 프로그램의 구조와 기본 문법

C 언어를 처음 배우면 코드는 마치 외계어처럼 보입니다. #include도 있고, 중괄호도 있고, 세미콜론도 잔뜩 붙어 있죠. 하지만 겁먹을 필요는 없습니다. C 코드는 일정한 뼈대를 반복해서 사용합니다. 그 뼈대만 읽을 수 있으면, 앞으로 만날 변수, 조건문, 반복문, 함수도 훨씬 덜 낯설어집니다.

보통 C 프로그램은 맨 위에 필요한 헤더 파일을 포함하고, 가운데에 main 함수를 두고, 필요하면 다른 함수들을 덧붙이는 구조를 가집니다.1 이번 장에서는 이 생김새를 눈에 익히는 데 집중하겠습니다.

C 프로그램의 구조와 기본 문법

가장 먼저 눈에 익혀야 할 코드

먼저 아주 짧은 C 프로그램을 보겠습니다.

#include <stdio.h>

int main(void)
{
    printf("안녕하세요, C!n");
    return 0;
}

이 코드는 짧지만, C의 핵심 뼈대가 거의 다 들어 있습니다.

첫 줄의 #include <stdio.h>는 표준 입출력 기능을 쓰겠다는 뜻입니다. 쉽게 말해 화면에 글자를 출력하거나, 키보드 입력을 받는 기능을 가져오는 준비 단계입니다.

그다음 int main(void)가 나옵니다. main 함수는 프로그램이 시작되는 지점입니다. 컴퓨터는 이 함수를 먼저 찾아서 실행합니다.2

중괄호 { } 안은 함수의 몸체입니다. 이 안에 실제로 실행할 문장들을 적습니다.

printf("안녕하세요, C!n");는 화면에 글자를 출력하는 문장입니다. 문장의 끝에는 세미콜론 ;이 붙습니다.

마지막의 return 0;은 프로그램이 정상적으로 끝났다는 뜻으로 이해하면 됩니다.2

이제부터 C 코드를 보면, 먼저 "헤더 파일이 있네", "아, main 함수가 시작되는구나", "중괄호 안에 실행 문장이 들어 있구나"라고 읽으면 됩니다. 코드를 해석하는 눈이 생기기 시작한 것입니다.

main 함수는 프로그램의 출발점

C 프로그램에서 가장 중요한 이름 하나를 꼽으라면 거의 언제나 main입니다. 운영체제는 프로그램을 실행할 때 이 함수를 시작점으로 삼습니다.2

초보자 단계에서는 다음 형태를 가장 기본으로 익히면 좋습니다.

int main(void)
{
    return 0;
}

여기서 int는 이 함수가 정수를 돌려준다는 뜻입니다. 그리고 return 0;은 그 정수 값이 0이라는 뜻입니다. 보통 0은 "정상 종료"를 의미합니다.2

가끔 인터넷에서 void main()을 볼 수도 있습니다. 어떤 컴파일러에서는 돌아갈 수 있지만, 표준적인 C 학습에서는 int main(void)를 쓰는 습관이 더 바람직합니다.2

나중에는 명령줄 인자를 받는 이런 형태도 보게 됩니다.

int main(int argc, char *argv[])

하지만 지금은 "프로그램은 main에서 시작한다"는 사실만 확실히 기억하면 충분합니다.

헤더 파일과 #include

C는 필요한 기능을 헤더 파일을 통해 불러오는 방식으로 많이 사용합니다. 헤더 파일은 함수 선언, 자료형, 매크로 같은 정보를 담고 있는 .h 파일입니다.3

예를 들어 printf()와 scanf()를 사용하려면 보통 stdio.h가 필요합니다.

#include <stdio.h>

이 줄은 "표준 입출력과 관련된 기능을 사용하겠다"는 선언처럼 생각하면 됩니다.3

헤더 파일을 포함하는 방법은 크게 두 가지입니다.3

  • #include <stdio.h>처럼 꺾쇠 괄호를 쓰는 방법

  • #include "myheader.h"처럼 큰따옴표를 쓰는 방법

  • 보통 표준 라이브러리 헤더는 < >, 내가 만든 헤더는 " "를 사용합니다

지금 단계에서는 stdio.h 하나만 자주 만나게 됩니다. 앞으로 문자열을 다룰 때는 string.h, 수학 함수를 쓸 때는 math.h 같은 헤더도 만나게 됩니다.

초보자에게 중요한 포인트는 단순합니다. "함수를 쓰려면, 그 함수가 어떤 헤더에 들어 있는지도 함께 챙겨야 한다"는 것입니다.

문장, 세미콜론, 중괄호

C 코드는 작은 문장들이 모여서 만들어집니다. 그리고 대부분의 문장은 세미콜론 ;으로 끝납니다.

int age;
age = 20;
printf("%dn", age);

위 코드에서 각 줄은 하나의 문장입니다. 마지막에 세미콜론이 빠지면 컴파일러는 매우 높은 확률로 투덜댑니다. 초보자가 가장 자주 만나는 실수 중 하나가 바로 이것입니다.

반면, 모든 줄 끝에 세미콜론이 필요한 것은 아닙니다. 예를 들어 #include 같은 전처리기 지시문은 세미콜론을 쓰지 않습니다.

중괄호 { }는 여러 문장을 하나의 블록으로 묶습니다. 함수의 몸체도 블록이고, 나중에 배울 if, for, while도 블록을 자주 사용합니다.

int main(void)
{
    printf("시작n");
    printf("끝n");
    return 0;
}

이 코드에서 중괄호 안의 세 문장은 모두 main 함수에 속합니다.

즉, 세미콜론은 "문장의 끝", 중괄호는 "블록의 시작과 끝"이라고 이해하면 됩니다. 이 둘만 구별해도 코드가 훨씬 덜 복잡해 보입니다.

주석은 컴퓨터가 아니라 사람을 위한 메모

주석은 프로그램 실행에 참여하지 않는 설명문입니다. 컴파일러는 주석을 무시합니다.4

C의 주석은 크게 두 가지가 있습니다.

// 한 줄 주석

/* 여러 줄 주석 */

짧은 설명에는 //가 편합니다.

int age = 20;  // 나이를 저장하는 변수

조금 긴 설명에는 /* ... */를 쓸 수 있습니다.

/*
   이 프로그램은
   한 줄의 문장을 출력한다.
*/

주석은 코드를 번역해 주는 자막 같은 역할을 합니다. 다만 모든 줄에 주석을 붙이면 오히려 더 읽기 어려워질 수 있습니다. "무엇을 하고 있는지"보다 "왜 이렇게 했는지"를 설명할 때 더 가치가 큽니다.

한 가지 주의할 점도 있습니다. 여러 줄 주석은 서로 겹쳐서 중첩할 수 없습니다.4 즉, /* ... /* ... */ ... */ 같은 형태는 문제가 생길 수 있습니다. 초보자라면 이 사실만 기억해도 큰 실수를 꽤 줄일 수 있습니다.

들여쓰기는 문법이 아니라 배려다

흥미롭게도 컴파일러는 들여쓰기를 거의 신경 쓰지 않습니다. 하지만 사람은 아주 많이 신경 씁니다.

다음 두 코드는 실행 의미가 같지만, 읽기 쉬움은 전혀 다릅니다.

int main(void) {
printf("Hellon");
return 0;
}
int main(void)
{
    printf("Hellon");
    return 0;
}

두 번째 코드가 훨씬 편하게 읽히죠. 들여쓰기는 "이 문장이 어느 블록 안에 들어 있는지"를 눈으로 바로 보여 줍니다.

초보자에게 추천하는 습관은 단순합니다.

  • 블록 안의 코드는 한 단계 들여쓴다

  • 한 줄에 한 문장씩 적는다

  • 중괄호 위치와 들여쓰기 방식은 끝까지 일관되게 유지한다

좋은 들여쓰기는 멋 부리기가 아니라, 미래의 나를 위한 친절입니다. 며칠 뒤 다시 봤을 때 "이게 내가 짠 코드 맞나?"라는 충격을 줄여 줍니다.

기본 입출력: printf와 scanf

이 장에서 가장 자주 만날 함수는 printf()와 scanf()입니다. 둘 다 보통 stdio.h를 통해 사용합니다.3

printf()는 화면에 출력할 때 사용합니다.

#include <stdio.h>

int main(void)
{
    printf("반갑습니다!n");
    return 0;
}

문자열 안의 n은 줄바꿈 문자입니다. 출력 후 커서를 다음 줄로 내려줍니다.

scanf()는 키보드 입력을 받을 때 사용합니다.

#include <stdio.h>

int main(void)
{
    int age;

    printf("나이를 입력하세요: ");
    scanf("%d", &age);
    printf("입력한 나이는 %d살입니다.n", age);

    return 0;
}

여기서 지금 꼭 알아둘 부분은 두 가지입니다.

첫째, "%d"는 정수를 뜻하는 서식 지정자입니다. 둘째, age 앞의 &는 그 변수의 주소를 뜻합니다. 주소는 나중에 포인터 장에서 자세히 배우겠지만, 지금은 scanf()가 값을 변수 안에 넣기 위해 변수의 위치를 알아야 한다고 가볍게 이해하면 충분합니다.

즉, 아주 단순하게 정리하면 printf()는 "보여 주는 함수", scanf()는 "받아 오는 함수"입니다.

코드를 읽을 때의 순서

초보자는 코드를 위에서 아래로 전부 같은 비중으로 읽으려다가 금방 지칩니다. 조금 더 편한 읽기 순서를 추천하면 다음과 같습니다.

  • 어떤 헤더 파일을 포함했는지 먼저 본다

  • main 함수가 어디서 시작하는지 찾는다

  • 중괄호로 묶인 블록의 범위를 본다

  • printf, scanf, 대입문 같은 실제 실행 문장을 읽는다

  • 마지막으로 주석을 참고해서 의도를 파악한다

이 순서로 보면 C 코드는 생각보다 정직합니다. 처음엔 낯설어 보여도, 사실은 늘 비슷한 자리에 비슷한 부품이 들어갑니다.

초보자가 자주 하는 실수

처음에는 누구나 비슷한 곳에서 걸립니다. 특히 아래 실수는 정말 자주 나옵니다.

  • 문장 끝의 세미콜론 ;을 빼먹는다

  • 중괄호 { }의 짝이 맞지 않는다

  • printf()나 scanf()를 쓰면서 #include <stdio.h>를 빼먹는다

  • scanf("%d", &age);에서 변수 앞의 &를 빼먹는다

이런 실수는 실력이 부족해서라기보다, 아직 손에 익지 않아서 생깁니다. 오타를 줄이는 가장 좋은 방법은 짧은 코드를 여러 번 직접 쳐 보는 것입니다.

이번 장의 핵심 정리

이제 여러분은 C 코드를 볼 때 최소한의 지도는 손에 쥔 셈입니다. main 함수가 어디인지, 헤더 파일은 왜 필요한지, 세미콜론과 중괄호는 어떤 역할을 하는지, 주석과 들여쓰기가 왜 중요한지, 그리고 printf()와 scanf()가 무엇을 하는지 알게 되었습니다.

아직 문법을 많이 외우지 않았더라도 괜찮습니다. 지금 단계의 목표는 "완벽하게 쓰기"가 아니라 "코드의 생김새를 읽을 수 있게 되기"입니다. 이 감각이 생기면 다음 장에서 배울 변수, 자료형, 상수, 연산자도 훨씬 자연스럽게 받아들일 수 있습니다.

다음 장부터는 이 뼈대 안에 실제 데이터를 담아 보겠습니다. 이제 빈 집 구조는 봤으니, 가구를 들여놓을 차례입니다.

참고

1Structure of the C Program - GeeksforGeeks

2Main function - cppreference.com

3Header Files in C - GeeksforGeeks

4C Comments - GeeksforGeeks

책 목록

초보자를 위한 C 언어 학습: 기초부터 프로젝트까지

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기