C언어) 전처리기 안내서 2

Lapis0875·2022년 12월 12일
0

c언어

목록 보기
15/21
post-thumbnail

📱전처리기의 세계를 여행하는 히치하이커들을 위한 안내서 (2)

전처리기를 잘 활용하면, 반복되는 코드를 줄이거나, 컴파일할 코드를 조건에 따라 변경하는 등 프로젝트를 개발할 때 있어 편리한 기능들이 많아요. 이번 편에는 헤더 파일과 조건부 컴파일에 대해 알아볼게요.

헤더 파일

.h 확장자를 가지는 파일들을 헤더 파일이라고 불러요. 헤더 파일에는 매크로를 정의하고, 함수의 원형과 기호 상수 등을 정의해둬요. 자주 사용하던 stdio.h, stdlib.h 등은 시스템이 제공하는 표준 헤더 파일들이에요.

사용자도 자신의 헤더 파일을 만들 수 있어요. 이 경우, 소스 파일과 같은 디렉터리에 위치시켜야 해요. 헤더 파일은 #include를 사용해 프로그램에 포함해요.

#include

#include 전처리 지시자는 뒤에 명시된 파일을 #include~ 문장 대신에 포함시켜요. 어떤 종류의 파일이건 사용할 수 있지만, 보통은 헤더 파일(.h)을 사용해요.

파일을 명시하는 방법은 두 가지 있어요.

  • #include <filename>
    - 표준 헤더 파일을 삽입할 때 사용해요.
    • 시스템에 정의된 경로에서 filename 파일을 찾아 삽입해요.
    • 일반적으로, 표준 헤더 파일이 저장된 장소는 시스템에 따라 달라요.
  • #include "filename"
    - 사용자 헤더 파일을 삽입할 때 사용해요.
    • 먼저 현재 경로에서 파일을 찾고, 만약 없을 경우에 시스템에 정의된 경로를 탐색해 삽입해요.

간단한 사용자 정의 헤더 파일을 만들어볼게요.

// pi.h
#include <stdio.h>
#define PI 3.14
double circumference(double);
double area(double);
// pi.c
#include "pi.h"
double circumference(double radius)
{
	return 2.0 * radius * PI;
}
double area(double radius)
{
	return radius * radius * PI;
}
// main.c
#include "pi.h"

int main()
{
	printf("반지름이 5인 원의 넓이 : %.3lf, 지름 : %.3lf\n", area(5.0), circumference(5.0));
	return 0;
}

💡 이 경우, main 함수를 실행하기 위해서는 pi.c와 main.c를 모두 빌드해야 해요!
pi.c와 main.c를 각각 오브젝트 파일로 컴파일해준 뒤, 이 오브젝트 파일들을 모두 사용해 컴파일하면 돼요.
아래와 같은 순으로 컴파일하면 돼요 :D
gcc -c pi.c
gcc -c main.c
gcc -o main pi.o main.o
./main

조건부 컴파일

전처리 지시자를 사용해, c언어 코드를 선택해서 컴파일 할 수 있어요. 이를 활용해, 플랫폼에 따라 다른 코드를 사용하는 등 프로그램의 이식성을 높일 수 있어요.

undef

앞서 정의된 매크로를 무효로 만드는 전처리 지시자에요.

#define PI 3.14
// ...
#undef PI
// 이 문장 아래로는 PI 매크로를 사용할 수 없어요.

undef는 매크로를 다시 정의할 때 주로 사용돼요.

if, elif, else, endif

c언어에 조건문이 있듯이, 전처리기도 조건문을 가져요.

#define YEAR 2022
#if YEAR < 2000
	int century = 20;
#elif YEAR < 2100
	int century = 21;
#else
	int century = 22;
#endif

전처리기의 조건문은 #if 로 시작해요. else if의 역할은 #elif가, else의 역할은 #else가 수행해요. 전처리기의 조건문은 반드시 #endif로 끝나야 해요.
#if#elif 뒤에는 정수 수식이 와요. #if#elif의 경우, 조건이 참일 때만 내부의 문장이 적용되고 그렇지 않으면 무시되요. 당연하게도, #else는 위 모든 조건이 거짓일때 내부의 문장을 적용해요.

defined()

defined는 명시된 식별자 (앞서 #defined로 정의한 매크로를 말해요.)가 정의되어 있는지를 확인하는 함수에요. 정의되어있는 식별자일 경우 1, 그렇지 않으면 0을 반환해요. #if 등의 구문에서 사용할 수 있어요.

#define PI
// ...
#if defined(PI)
	#undef PI
    #define PI 3.141592
#endif

ifdef, ifndef

#ifdef, #ifndef뒤에는 식별자가 와요. 뒤에 온 식별자가 #define으로 정의되어있는지 확인해서, 정의되어 있을 경우 내부의 문장을 적용해요.

#ifdef PI
	#undef PI
    #define PI 3.141592
#endif

#ifdef#if defined(식별자)와 동일한 기능을 해요. 이 또한 조건문이기 때문에, #endif로 끝나야 해요.

profile
새내기 대학생 개발자에요 :D

0개의 댓글