선행처리
컴파일러가 파일을 컴파일하기 전 선행처리기에 의해서 일어나는 처리과정을 선행처리라고 한다.
오브젝트 유사 매크로 (Object-like macro)
오브젝트 유사 매크로를 사용하는 방법은 define 지시자를 명시해 주고 매크로 이름과 매크로 몸체를 명시해 주면 된다.
이것은 단순히 코드 안의 매크로를 매크로 몸체로 치환하는 역할을 한다.
#define PI 3.14
즉 해당 파일 안의 모든 PI를 3.14로 치환하겠다는 의미이다.
매크로 함수 (Function-like macro)
매크로 함수의 선언도 오브젝트 유사 매크로와 동일하게 define 지시자를 명명해 주면 된다.
예를 들어서 함수 하나를 작성해보겠다.
#define SQUARE(X) X*X
위 코드처럼 작성하면 파일 내의 SQUARE(X)를 X*X로 치환하겠다는 의미이다.
SQUARE(123);
SQUARE(NUM);
따라서 위 코드는 다음과 같이 치환된다.
123*123
NUM*NUM
그런데 위 코드처럼 작성했을 경우 문제가 발생할 수 있다.
만약 SQUARE(2+3)을 실행하게 되면 SQUARE(X)의 X에 해당하는 부분, 즉 2+3 이 치환되는 것이기 때문에
SQUARE(2+3)은 2+3*2+3으로 치환된다.
따라서 5의 제곱인 25가 되는 것이 아니라 11로 치환 돼버린다.
이럴 때 소괄호를 쳐 주는 것으로 문제를 해결할 수 있다.
#define SQUARE(X) (X)*(X)
이렇게 하면 SQUARE(2+3)은 (2+3)*(2+3)으로 치환되므로 원하는 값을 얻을 수 있다.
하지만 문제는 아직도 남아있다.
int num = 250/SQUARE(5);
위와 같은 코드를 작성하였을 경우 SQUARE(5)는 (5)*(5)로 치환된다.
따라서 num = 250/(5)*(5); 로 계산이 진행되므로 num에는 250이 대입된다.
결국 우리가 원하는 값을 얻기 위해서는 다음과 같이 작성해야 한다.
#define SQUARE(X) ((X)*(X))
괄호를 마구마구 쳐 주는 것이 해결책이 될 수 있다.
참고로 매크로 함수를 작성할 때 가독성을 위해 두 줄 이상에 걸쳐 정의할 수도 있는데 그럴 때에는 아래 코드와 같이
\기호를 사용하여 정의해 주면 된다.
#define SQUARE(X) \
((X)*(X))
매크로를 사용한 매크로 정의
매크로를 정의할 때 먼저 정의된 매크로를 사용하는 것도 가능하다.
따라서 원의 넓이를 구하는 매크로를 다음과 같이 정의할 수 있다.
#define PI 3.14
#define SQUARE(X) ((X)*(X))
#define CIRCLE_AREA(R) ((SQUARE(R))*(PI))
매크로 함수의 장점
이렇게 복잡한 매크로 함수를 사용하는 이유는 일반적인 함수에 비해서 실행속도가 빠르다는 장점이 있기 때문이다.
또한 자료형에 따라서 별도로 함수를 정의하지 않아도 된다.
'C언어 > C언어 문법' 카테고리의 다른 글
[C언어] 파일 입출력, 파일 스트림 생성 (fopen, fclose) (0) | 2024.02.28 |
---|---|
[C언어] 조건부 컴파일 매크로 (#if, #elif, #endif, #ifdef, #ifndef) (0) | 2024.02.25 |
[C언어] 구조체의 중첩 (0) | 2024.02.25 |
[C언어] 함수로의 구조체 변수 전달과 구조체 반환 함수 (0) | 2024.02.24 |
[C언어] 사용자 정의 자료형(typedef), 구조체 typedef 선언 (0) | 2024.02.23 |