이번 포스팅에서는 전처리 지시자에 대해서 작성해보려고 합니다.
대부분의 전처리 지시자들은 세 가지로 분류될 수 있습니다.
#define
지시자는 매크로를 정의해준다#undef
지시자는 매크로 정의를 없애준다#include
지시자는 특정 파일의 내용물을 프로그램에 추가해준다.#if
, #ifdef
, #ifndef
,#elif
,#else
, `#endif 지시자들은 전처리가 확인할 주어진 조건에 따라 코드의 특정 부분을 프로그램에서 추가하거나 제외할 수 있다.나머지 지시자들인 #error
, #line
, #pragma
는 좀 더 특수한 목적을 갖고 있어 그리 자주 사용되지는 않는다.
전처리 지시자에 대해서 정리하기 전에, 모든 지시자들에 적용되는 몇 가지 규칙을 알아보도록 하자
#
기호로 시작한다. #
기호 이전에 공란문자가 있기만 하면 굳이 해당 줄은 반드시 #
기호로 시작할 피요는 없다. #
기호 이후에는 지시자의 이름과 해당 지시자가 필요로 하는 다른 정보들이 온다#define N (100)
\
문자로 끝내야 한다#define DISK_CAPACITY (SIDES * \
TRACKS_PER_SIDE * \
SECTORS_PER_TRACK * \
BYTES_PER_SECTOR)
#define
이나 #include
지시자를 파일의 시작부에 놓기는 하지만 다른 지시자들은 나중에, 심지어 함수 정의 중간에서도 나올 가능성이 더 높다.매크로 함수는 함수처럼 인자를 설정할 수 있는 매크로를 의미합니다.
매크로 상수와는 달리 매크로 함수 이름에 괄호 와 함께 인자 목록이 주어져 있습니다.
매크로 함수라고 부르지만 단순히 치환하기만 하므로 실제로 함수는 아닙니다.
함수 선언과 비슷하지만 매크로 함수는 인자의 자료형을 신경 쓰지 않습니다.
즉, 자료형의 독립성을 보장합니다. 또 매크로 함수 내부에서 자기 자신을 호출할 수 없다는 특징이 있습니다.
매크로를 정의하는 경우에는 컴파일이 되면 해당 매크로 이름을 가진 것들이 지정해놓은 값으로 변해서 컴파일 됩니다.
#define (매크로 함수 이름) (매크로 함수 기능)
#define ADD(a,b) a+b //ex
`#define으로 시작되는 전처리 문장을 매크로라고 하며 이를 사용하여 매크로 함수를 만들 수 있습니다.
매크로 함수 사용 예제
#include <stdio.h>
#define ADD(x,y) x+y
int main()
{
int num1 = 10;
int num2 = 20;
printf("매크로 함수(ADD) : %d + %d = %d\n", num1, num2, ADD(num1, num2));
return 0;
}
#include <stdio.h>
#define MUL1(x,y) x*y
#define MUL2(x,y) (x)*(y)
int main()
{
int num1 = 5;
int num2 = 4;
printf("매크로 함수(MUL1) : %d * %d = %d\n", num1 + 1, num2 + 1, MUL1(num1 + 1, num2 + 1)); // num1 + 1 * num2 + 1로 변환
printf("매크로 함수(MUL2) : %d * %d = %d\n", num1 + 1, num2 + 1, MUL2(num1 + 1, num2 + 1)); // (num1 + 1) * (num2 + 1)로 변환
return 0;
}
매크로 함수는 num1+1, num2+2를 단순히 x와 y의 위치에서 단순히 치환하기 때문에 괄호를 제대로
사용하지 않는다면 위와 같은 문제점이 발생할 수 있습니다.
곱셈처럼 연산순서에 따라 결과가 달라질 수 있다면 어떠한 인자값이 들어올 지 모르니 매크로 함수의
기능에 명시적으로 괄호를 처리해주어 잘못 연산되는 것을 방지해야 한다
ex. 안 좋은 예시 : ADD(x, y) x + y
좋은 예시 : ADD(x,y) ((x) + (y))
매크로 함수와 인라인 함수는 작동방식과 결과에 대해서는 매우 유사하지만 차이점도 있습니다.
inline 함수의 경우
컴파일 단계(Compiling)에서 처리가 이루어집니다. (인라인 하느냐 vs 안되느냐)
일반적인 함수들을 위해 실행하는 타입 검사가 그대로 적용됩니다.
macro 확장자의 경우
전처리 단계(Preprocessing)에서 치환이 이루어집니다.
대치 시 어떠한 타입 검사도 이루어지지 않습니다.
Standard Input Output, 즉 표준 입출력을 의미한다. studio가 아니다.
C언어를 처음 접하는 사람들이 많이 실수하는 부분이다(가끔씩 자동완성 안 뜨고 급하게 작성하다 보면
실수 할 때가 많다)
C언어의 표준 입/출력 헤더 파일로, printf나 scanf 처럼 콘솔 입/출력을 할 때, 외부 파일을
읽을 때 사용한다. 기초 프로그래밍 교육이 대부분 Hello World 출력부터 시작해, 대부분 CLI
환경을 다루는 것에 그친다는 것을 생각하면, C/C++을 배우면서 자주 보게 되는 헤더 파일이다.
시간 관련 부분함수 구조체를 담고있는 헤더로 시간관련 부분을 불러오거나 사용할 때 사용한다
지수함수, 로그함수, 삼각함수, 거듭제곰 등 수학 관련 함수가 들어가 있다
문자열 변환, 의사 난수 생성, 동적 메모리 관리 등의 함수들을 포함하고 있다.
주로 프로그램 제어 관련 함수가 들어가 있다. 동적 메모리 할당 함수인
malloc, calloc 함수도 이 헤더에 포함되어 있으며, 시스템 명령어나 프로세스 제어 함수도 포함되어 있다.
문자열(정확히는 문자 배열 - char* str 또는 char str[]) 관련 헤더이다.
등의 함수가 있다.