C언어 강의를 들으면 항상 처음에 등장하는 코드가 있다.
#include <stdio.h>
이것은 그냥 써야하는 코드일까?
1. 전처리기(Preprocesser)
전처리 프로그램. 컴퓨터 처리에서 중심적인 처리를 행하는 프로그램의 조건에 맞추기 위한 사전 처리나 사전 준비적인 계산 또는 편성을 행하는 프로그램
우리가 코드를 작성하고 그 코드(소스파일)를 컴파일러가 기계어로 변경해주면서 컴퓨터가 프로그램을 실행할수 있게 된다.
그런데 이 컴파일러에는 전처리기(Preprocesser)라는 모듈이 포함되어 있고 작성한 코드(소스파일)를 컴파일러가 기계어로 컴파일 하는 작업을 하기 전에 먼저 전처리기가 전처리 작업을 수행하게 된다.
이때 전처리 작업을 지시하는 문자가 #명령어인 것이고 이를 전처리기 지시자 혹은 전처리 지시자라고 부른다.
2. 전처리 지시자(Preprocessor Directives)
전처리 지시자를 사용할때엔 유의할 점이 있다.
전처리 지시자들은 아래 네가지로 분류 된다.
1) 메크로의 확장 지시자
#define -> 메크로 정의(상수, 함수를 정의할수 있다.)
ex) #define macro_name value
#define three 3
three라는 이름을 사용할경우 3으로 치환한다
#define plus(x,y){x+y}
plus(x,y)라는 함수를 선언 했고 나중에 plus(3, 4)와 같이 사용할수 있다.
#undef -> 메크로 정의 해제
ex) #undef macro_name
#undef three
three라는 이름의 메크로의 정의를 제거한다.
#undef plus(x,y)
plus라는 이름의 메크로의 정의를 제거한다.
2) 조건부 컴파일 지시자
조건부 컴파일 지시자는 조건에 따라 소스코드의 해당 부분의 컴파일 여부를 제어한다.
플랫폼, 운영체제를 구분하며 컴파일, 디버깅, 테스트등에 사용한다.
#if -> 조건이 참일 경우
ex)
#if 조건
실행할 코드
#else -> 조건이 거짓일 경우
ex)
#if 조건
실행할 코드
#else
실행할 코드
#elif -> #if의 조건의 분기를 지정한다
ex)
#if 조건
실행할 코드
#elif 조건1
실행할 코드
...
#elif 조건n
실행할 코드
#else
실행할 코드
#endif -> 조건부 컴파일 종료
ex)
#if 조건
실행할 코드
#else
실행할 코드
#endif
return ;
#ifdef -> 메크로가 정의되어 있는 경우
ex)
#ifdef define_name
실행할 코드
#else
실행할 코드
#ifndef -> 메크로가 정의되어 있지 않은 경우
ex)
#ifndef define_name
실행할 코드
#else
실행할 코드
여기서 조건이 0일 경우 컴파일 자체가 실행되지 않는다.
#if의 경우는 메크로 내부의 값이 0인가 아닌가가 중요하지만
#ifdef 혹은 #ifndef의 경우는 메크로가 존재하는가 존재하지 않는가가 중요하다.
#define macro 0 이 존재할 경우, #if의 경우는 내부에 0이 들어 있기에 컴파일이 자체가 되지 않으나 #ifdef의 경우는 메크로가 정의되어 있기 때문에 컴파일이 된다.
3) 외부 파일 지시자
#include -> 파일을 포함시킨다.
ex)
#include <file_name> -> c언어 컴파일 내 설정된 include 디렉토리에서 해당 파일을 찾아 포함시킨다.
#include "file_name" -> 해당 파일을 현재 소스파일이 있는 디렉토리에서 파일을 찾고 없다면 include 디렉토리를 찾아 포함시킨다.
4) 기타 지시자
#error -> 에러메세지에 대한 명령을 지시(설정해둔 에러 메세지를 출력, 전처리과정에서 컴파일 중지)
ex)
#error 출력하고자 하는 문장 작성(", ', ; 등 특수기호가 필요하지 않음)
**보통은 컴파일 하기 위한 조건에 넣어주는 편(컴파일 될수 있는 상황이 아니기에 에러를 발생시키면서 컴파일이 안된 이유, 에러 발생 원인을 작성해주는것)
그렇기에 조건부 컴파일 지시자와 함께쓴다
#line -> __LINE__과 __FILE__를 재정의 하는데 사용한다.
ex)
#line 1 file_name.c
printf(__LINE__);
printf(__FILE__);
#line이 호출된 라인를 0으로 하고 그 아래부터 라인 숫자를 세어 __LINE__에 호출되는 라인을 반환한다.
또한 __FILE__를 호출하면 #line에 지정한 파일 이름을 반환한다.
5) 전처리기가 아닌 컴파일러에게 지시를 내리는 #pragma 지시자
#pragma지시자는 지금 여기서 설명하기에 너무 많기에 나중에 추가 서술하기로 하자...
C언어도 서술할것들이 너무 많아 하나 찾아보고 하나 작성하는데 시간이 너무 많이 걸리는 것 같다...좀 더 효율적인 방법이 없을까 고민해봐야 겠다..
아주 유용한 정보네요!