C언어: 헤더 파일
헤더 파일은 근본적으로 .c 확장자를 가진 소스 파일과 차이가 없다.
그러나 자주 사용되는 함수 프로토타입들과 전역 변수, 매크로 등을 담고 있으며 include 용으로 쓰이는 소스 파일들을 헤더 파일이라 칭할 뿐이다.
유저가 생성한 헤더 파일을 include 하기 위해서는
#include "file.h"
의 형태를 사용한다.
이 경우, preprocessor는 현재 경로나 working directory를 탐색한 이후 시스템 헤더 파일 위치를 탐색한다.
"/home/masterjunmo/headers/file.h"
와 같이 절대 경로를 입력하는 것도 가능하다. 그러나 portability가 훼손되므로 자제하는 것이 좋다.
컴파일 시 -Ipath
등의 옵션을 통해 탐색할 경로를 지정 가능하다.
헤더 파일에 포함되는 요소
-
함수 프로토타입 (Declaration)
-
Macro Definitions
-
Type Definitions
-
External Variables
-
Structure Type Declarations
함수가 다른 소스 파일(.c) 에 정의되어 있을 때,
같은 이름의 헤더 파일(.h)에 해당 함수의 프로토타입만을 선언하고, (단, 함수가 정의된 소스 파일 내에서만 사용되는 함수는 선언하지 않는다.)
함수가 정의된 해당 소스 파일 (프로토타입과 정의가 일치하는지 확인하기 위해) + 해당 함수를 호출하는 모든 소스 파일에서 include 함으로써 사용 가능하다.
이때, 함수가 정의된 소스 파일을 따로 include 할 필요는 없다.
-> 컴파일 시, 해당 소스 파일들을 같이 컴파일하면 된다.
ex)
gcc -o justify justify.c line.c word.c
컴파일 시, 각 소스 파일들이 object code (.o) 로 변환된다.
이후, 링크 과정을 통해 각 object code들을 하나의 executable file로 만들어준다.
그런데 애초에, 왜 헤더 파일 자체에 함수의 정의와 선언을 동시에 하면 안 되는 것인가?
-> 해당 헤더파일을 여러 파일에 include 후 컴파일할 때, 같은 소스 코드를 여러 번 컴파일하게되는 문제가 발생한다. 그렇게 되면 같은 함수에 대한 object code의 복사본이 여러 개 만들어진다. 이는 링크 과정에서 문제 발생의 여지가 있다. 이는 소스 코드 자체를 include할 때 발생하는 문제와 같다.
external variables(전역 변수)의 경우
-
하나의 소스 파일에 변수를 ‘정의’ 한다:
int i;
(필요 시 초기화) -
헤더 파일에는 해당 변수를 ‘선언’한다:
extern int i;
-
그러나, 같은 변수를 공유하는 서로 다른 파일들의 경우 문제가 발생할 여지가 많다. (자세한 것은 추후 다룰 예정이다.)
중복 inclusion 방지법
#ifndef
- #endif
pair를 활용한다. (헤더파일의 시작과 끝)
Example)
#ifndef BOOLEAN_H //flag 역할, 헤더 파일과 이름을 닮게 하는 것이 좋다.
#define BOOLEAN_H
#define TRUE 1
#define FALSE 0
typedef int Bool;
#endif
참고로 C++에서는 #pragma once
한줄만 추가하면 끝이다.