이번 편의 목표: 함수 선언은 헤더에, 함수 본문은 소스 한곳에 두고, 파일 두 개를 함께 컴파일합니다.

프로그램이 커지면 모든 함수를 main 파일에 두지 않습니다. 헤더는 다른 파일이 호출해도 되는 선언을 공개합니다. 소스 파일은 그 선언의 본문을 한 번만 정의합니다.

book.h입니다.

C
#ifndef BOOK_H
#define BOOK_H

int late_fee(int days);

#endif

#ifndef와 #define은 같은 헤더가 한 번역 단위에 두 번 포함되어도 선언이 한 번만 보이게 막습니다. 이 세 줄을 포함 보호대라고 부릅니다.

book.c입니다.

C
#include "book.h"

int late_fee(int days) {
    return days * 100;
}

main.c입니다.

C
#include <stdio.h>
#include "book.h"

int main(void) {
    printf("%d\n", late_fee(3));
    return 0;
}

꺾쇠 포함은 컴파일러가 제공하는 헤더를 찾고, 따옴표 포함은 먼저 현재 프로젝트를 찾습니다. 컴파일은 소스 파일을 모두 적습니다.

gcc -std=c17 -Wall -Wextra -o library main.c book.c

./library

출력은 300입니다. 헤더에 함수 본문을 넣으면 그 헤더를 포함하는 소스마다 정의가 생겨 링크에 실패할 수 있습니다. 선언과 정의를 나누는 이유가 여기 있습니다.

직접 해 보기

late_fee의 하루 요금을 150으로 바꾸고, main.c는 수정하지 않은 채 다시 컴파일해 5일의 요금을 출력하도록 main의 인자만 조정해 보세요.

해설

계산식은 book.c에만 있습니다. days가 5이고 하루가 150이면 750입니다. 헤더의 선언은 int를 주고받는다는 약속만 유지하면 됩니다.