매크로와 전처리기 (Preprocessor).
Programming/C 2013. 2. 15. 03:23 |전처리기 : 소스코드는 컴파일러에 의해서 컴파일 되기 이전에, 전처리기라는 것에 의해서 전처리기 과정을 거치게 된다.
전처리기가 하는 일 : 단순히 치환(substitution)의 형태를 띠는 경우가 대부분.
#define : Object-like macro
#define PI 3.14
int main()
{
.....
num = PI * 3.5; // 전처리기로 전처리 과정을 거치게 되면 num = 3.14 * 3.5 가 된다.
....
}
전처리 명령문은 # 문자로 시작을 하며, 컴파일러가 아닌 선행처리기에 의해서 처리되는 문장이기 때문에 명령어의 끝에 세미콜론을 붙이지 않는다.
#define PI 3.14
↑지시자 ↑매크로 ↑매크로 몸체('매크로 상수'라고도 불림.)
결과적으로 PI라는 이름의 매크로는 그 자체로 상수 3.14가 된 셈이다. 참고로 PI와 같은 매크로를 가리켜 '오브젝트와 유사한 매크로(object-like macro)'라 한다.
※ 오브젝트(object)라는 것은 그 자체로 "완전한 의미를 갖는 대상이나 사물"을 의미한다. 그런데 위에서 정의한 매크로 PI는 그 자체로 3.14라는 상수를 의미하기 때문에 "오브젝트와 유사한 매크로" 라고 한다.
※ 매크로는 대문자로 정의하는 것이 일반적이다. 대문자로 정의함으로 인해서 변수나 함수의 이름과는 쉽게 구분이 되고, 이 식별자가 매크로라는 사실을 부각시킬 수 있기 때문이다.
#define : Function-like macro
(매크로 함수)
: 매크로는 매개변수가 존재하는 형태로도 정의할 수 있다. 그리고 이렇게 매개변수가 존재하는 매크로는 그 동작방식이 마치 함수와 유사하여 '함수와 유사한 매크로(function-like macro)' 라 하는데, 줄여서 "매크로 함수" 라고도 부른다.
#define SQUARE(X) X*X
↑이러한 패턴 등장 시 ↑이러한 유형으로 바꿔라
위의 정의를 접한 전처리기는 SQUARE(X)와 동일한 패턴을 만나면, 무조건 X*X로 치환해버린다.
매크로 확장(macro expansion)
※ 기본 적으로 매크로는 한줄에 정의하는 것이 원칙이다. 하지만 가독성을 높이기 위해서 두 줄에 걸쳐서 매크로를 정의할 수 있다.
이럴땐 \문자를 활용해서 줄이 바뀌었음을 명시해야 한다.
#define SQUARE(X) \
((X)*(X))
매크로 정의 시, 먼저 정의된 매크로도 사용 가능.
매크로 함수의 장점
:매크로 함수를 정의하는 것은 일반 함수를 정의하는 것보다 어렵다. 그리고 정의하고자 하는 함수의 크기가 크면, 매크로로 정의하는 것 자체가 불가능할 수도 있다. 그럼에도 불구하고 함수를 매크로로 정의하는 이유는?
1. 매크로 함수는 일반 함수에 비해 실행속도가 빠르다. (일반 함수는 호출된 함수를 위한 스택 메모리의 할당, 실행위치의 이동과 매개변수로의 인자 전달, return문에 의한 값의 반환이 일어난다. 그래서 일반 함수의 빈번한 호출은 실행속도의 저하를 가져온다.)
2. 자료형에 따라서 별도로 함수를 정의하지 않아도 된다. (SQUARE를 보면, 전달인자의 자료형에 상관이 없음을 알 수 있다. 이 모두가 매크로 함수의 호출 문장이 매크로 함수의 몸체 부분으로 단순히 치환되기 때문에 가능한 일이다.)
매크로 함수의 단점
1. 정의하기가 까다롭다.
#define DIFF_ABS(X, Y) ((X) > (Y) ? (X)-(Y) : (Y)-(X)) 삼항 연산자를 활용하였는데..
if~else 문으로 바꾸면 이렇다.
int DiffABS(int a, int b)
{
if(a>b)
return a-b;
else
return b-a;
}
2. 디버깅하기가 힘들다. (매크로를 잘못 정의할 경우, 에러 메시지는 선행처리기를 기준으로 출력되지 않고, 컴파일러를 기준으로 출력이 된다. 따라서 일반적인 에러 메시지보다 이해하기 힘들다.)
매크로 함수의 장점과 단점을 종합한 결론.
ⓐ 함수의 크기 또는 길이가 짧은 함수. (함수의 크기 또는 길이가 짧아야 매크로의 형태로 정의하기가 편리하고 에러의 발생 확률이 낮아서 디버깅에 대한 염려를 덜 수 있다.)
ⓑ 호출이 되는 빈도수가 높은 함수. (호출의 빈도수가 높아야 매크로 함수가 가져다 주는 성능 향상의 이점도 최대한 누릴 수 있다.)
'Programming > C' 카테고리의 다른 글
조건부 컴파일(Conditional Compilation) (0) | 2013.02.15 |
---|---|
#error, #pragma 및 #line (0) | 2013.02.15 |
실행파일이 만들어 지는 과정. (0) | 2013.02.15 |
sprintf 함수, sscanf 함수 (0) | 2013.02.15 |
문자열 컨트롤 함수 (strlen, strcpy, strcat, strstr, strchr, strtok, atoi 등..) (0) | 2013.02.15 |