전처리기 (preprocessor)
컴파일러는 전처리문을 읽고 해석하고 처리하여 코드로 변환한 뒤 원래 전처리문은 코드에서 제거한다.
예)
main.c
#define HELLO printf("hello\n")
int main() {
HELLO;
}
전처리 후
int main() {
printf("hello\n");
}
- 위 과정은 컴파일러가 해석하는 부분이기 때문에 정확히 위와 같이 코드가 생성되지는 않겠지만
- 컴파일 결과물은 전처리 후 코드와 같은 동작을 한다.
아래와 같은 전처리문들이 있다.
- #include
- #if
- #else
- #elif
- #endif
- #define
- #ifndef
- #ifdef
- #error
- #warning
특징을 보면 # 으로 시작한다는 점을 알 수 있다.
- #include : 이미 보았겠지만 header 파일을 포함시킨다.
- #if 조건문 : 분기문
- #else : #if 조건문이 거짓인 경우
- #endif : #if 문의 끝
- #define 정의값 대체문 : 사용자 값 정의
- #ifndef 정의값 : 정의값이 존재하는지 않는지 판단
- #ifdef 정의값 : 정의값이 존재하는지 판단
- #error 경고 문구 : 컴파일 에러 유발 (컴파일 시 경고 문구 출력)
- #warning 경고 문구 : 컴파일 중 경고 문구 출력
예)
#ifdef __unix__
# inculde <unistd.h>
#elif define _WIN32
# include <Windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define LOG printf
int main() {
LOG("Hello World\n");
}
위 코드는 unix 플랫폼일 때와 windows 플랫폼일 때 다르게 변화한다.
unix 플랫폼
#inculde <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello World\n");
}
windows 플랫폼
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello World\n");
}
unistd.h 헤더는 unix 계열 플랫폼에서만 참조할 수 있고 Windows.h 는 windows 계열 플랫폼에서만 참조할 수 있다.
__unix__ 나 _WIN32 등의 define 값은 컴파일러에 의해 미리 정의 된 값이다.
typedef
변수 타입을 추가한다.
문법:
typedef <유효한 C 타입> <새로운 타입명>;
반드시 유효한 C 타입만 typedef 처리할 수 있다.
예)
typedef int mynumber;
...
mynumber number = 10;
mynumber 는 컴파일 과정에서 int 로 대체된다.
예)
- typedef char mycharacter;
- typedef char* mystring;
- typedef unsigned char uint8;
- typedef unsigned int uint32;
char, short, int 라는 의미보다 데이터 크기가 중요한 경우 type 크기를 이름에 붙이기도 한다.
- typedef unsigned char myuint8;
- typedef unsigned short myuint16;
- typedef unsigned int myuint32;
구조체 변수 선언문을 다시 보면 이렇다.
struct my_struct_t var;
typedef 로 지정하면 아래와 같이 사용할 수 있다.
typedef struct my_struct_t my_struct;
my_struct var;
enum
여러 상수를 열거하는 식으로 선언한다.
예)
enum my_enum {
left,
right,
down,
up
};
- 위 문을 실행하면 left, right, down, up 이라는 상수가 자동으로 생성된다.
- 자동으로 left = 0, right = 1, down = 2, up = 3 값이 지정된다.
마치 이런 코드와 같은 처리를 한다.
const int left = 0;
const int right = 1;
const int down = 2;
const int up = 3;
enum 변수 선언:
enum my_enum var;
enum 변수 참조:
var = left;
enum 변수 비교문:
switch (var) {
case left;
break;
case right:
break;
case down:
break;
case up:
break;
}
enum 상수 초기값 변경
기본으로 0 1 2 3 ... 순으로 지정이 되지만 초기값을 변경할 수 있다.
예)
enum direction {
north = 1,
south,
west,
east
};
north 값부터 1씩 더해 간다.
north = 1 ,south = 2, west = 3, east = 4 가 된다.
enum direction {
north,
south = 5,
west,
east
};
north = 0 ,south = 5, west = 6, east = 7 가 된다.
Cross platform 대응
전처리문 예를 보면 unix 에서 사용할 수 있는 헤더 파일과 windows 에서 사용할 수 있는 헤더 파일이 다르다.
뿐만 아니라. 지원하는 함수들도 다르다.
하지만 일맥상통하는 부분은 같거나 비슷한 기능을 제공하고 있다는 점이다.
다만 함수 이름이나 사용법이 다를 뿐이다.
이런 경우 전처리기와 typedef 문을 잘 활용하면 하나의 소스 코드로 여러 플랫폼에 컴파일 했을 때 문제가 없게 작성할 수 있다.
이러한 처리가 되어 소스 코드 하나로 여러 플랫폼에서 컴파일 할 수 있는 코드를 cross platform 한 코드라고 한다.
댓글 없음:
댓글 쓰기