76.3 파일 포함하기
드디어 여러분들께 비밀을 밝힙니다. #include 앞에 #이 왜 쓰였을까요? #include도 전처리기이기 때문입니다(#은 전처리기를 호출하는 특별한 문법입니다).
#include 지시자는 헤더 파일(.h)과 소스 파일(.c)를 포함합니다.
- #include <파일>
- #include "파일"
#include에 헤더 파일을 지정할 때 < > (홑화살괄호)를 사용하기도 하고, " " (큰따옴표)를 사용하기도 합니다. 홑화살괄호와 큰따옴표의 차이는 다음과 같습니다.
- < >: 보통 C 언어 표준 라이브러리의 헤더 파일을 포함할 때 사용합니다. 또한, 컴파일 옵션에서 지정한 헤더 파일 경로를 기준으로 파일을 포함합니다.
-
" ": 현재 소스 파일을 기준으로 헤더 파일을 포함하고, 헤더 파일을 찾지 못할 경우 컴파일 옵션에서 지정한 헤더 파일 경로를 따릅니다(솔루션 탐색기에서 프로젝트 선택 > 메인 메뉴의 프로젝트(P) > 속성(P) > C/C++ > 일반 > 추가 포함 디렉터리).
- 예) "message.h": 현재 소스 파일과 같은 경로에 있는 message.h 파일을 포함합니다.
- 예) "inc/message.h": 현재 소스 파일 경로에서 inc 디렉터리 아래의 message.h 파일을 포함합니다.
- 예) "../message.h": 현재 소스 파일 경로의 상위 디렉터리에 있는 message.h 파일을 포함합니다.
먼저 헤더 파일을 만들어보겠습니다. 왼쪽 메뉴에서 헤더 파일을 선택한 뒤 마우스 오른쪽 버튼을 클릭하면 팝업 메뉴가 나옵니다. 그리고 추가(D) > 새 항목(W)...을 클릭합니다.
파일 추가 창이 표시됩니다. 먼저 헤더 파일(.h)를 선택한 뒤 이름(N)에 message.h를 입력하고 추가(A) 버튼을 클릭합니다.
헤더 파일이 추가되었으면 message.h 파일에 다음과 같이 입력합니다.
message.h
#if defined EN #define HELLO_MESSAGE "Hello" #elif defined KO #define HELLO_MESSAGE "안녕하세요" #elif defined FR #define HELLO_MESSAGE "Bonjour" #endif
이제 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
include.c
#include <stdio.h> #define KO // KO 매크로 정의 #include "message.h" // message.h 헤더 파일 포함 int main() { printf("%s\n", HELLO_MESSAGE); // 안녕하세요: message.h에 정의한 HELLO_MESSAGE의 값이 출력됨 // KO 매크로가 정의되어 있으므로 HELLO_MESSAGE는 "안녕하세요"가 됨 return 0; }
실행 결과
안녕하세요
#include를 사용하여 message.h 헤더 파일을 포함했습니다.
#define KO // KO 매크로 정의 #include "message.h" // message.h 헤더 파일 포함
현재 소스 코드에는 HELLO_MESSAGE 매크로가 없지만 message.h 헤더 파일 안에 HELLO_MESSAGE 매크로가 정의되어 있으므로 다음과 같이 매크로의 값을 출력할 수 있습니다. 여기서 #include 위에 #define으로 KO를 정의했으므로 message.h에도 KO가 적용되어 #elif KO 부분의 #define HELLO_MESSAGE "안녕하세요"가 컴파일됩니다(#include 아래에 KO를 정의하면 적용되지 않으므로 주의합니다).
printf("%d\n", HELLO_MESSAGE); // 안녕하세요: message.h에 정의한 HELLO_MESSAGE의 값이 출력됨 // KO 매크로가 정의되어 있으므로 HELLO_MESSAGE는 "안녕하세요"가 됨
다른 언어를 사용하고 싶다면 #include "message.h" 위에 KO 대신 EN이나 FR을 정의하면 됩니다. 지금까지 책에서 C 언어 표준 함수의 보안 경고로 인한 컴파일 에러를 방지하기 위해 #include <stdio.h> 위에 #define _CRT_SECURE_NO_WARNINGS처럼 정의해준 것도 예제와 같은 원리입니다. 즉, _CRT_SECURE_NO_WARNINGS가 정의되어 있으면 Visual Studio에서 제공하는 함수 대신 C 언어 표준 함수를 선택해서 사용합니다.
이처럼 헤더 파일을 포함하면 헤더 파일 안에 정의된 매크로나 선언된 함수 등을 사용할 수 있습니다.
#include는 #ifdef, #if 등과 조합하여 특정 조건에서만 헤더 파일을 포함할 수 있습니다.
#define DEBUG #ifdef DEBUG // DEBUG가 정의되어 있다면 debug_message.h 헤더 파일 포함 #include "debug_message.h" #else // 아니면 message.h 헤더 파일 포함 #include "message.h" #endif
지금까지 조건부 컴파일과 파일 포함에 대해 배웠는데 코드에 매크로가 섞이다 보니 알아보기가 쉽지 않았습니다. 실제로 C 언어로 작성된 프로그램의 소스 코드를 보면 매크로와 조건부 컴파일을 상당히 많이 사용합니다. 특히 멀티 플랫폼을 지원하는 프로그램은 매크로와 조건부 컴파일을 복잡하게 사용합니다. 당장은 모든 내용을 익힐 필요는 없으며 나중에 규모가 큰 프로그램의 소스 코드를 분석해야 할 때 다시 돌아와서 복습하면 됩니다.