이전에 #define문을 이용한 상수의 정의를 살펴보았는데 이번에는 매크로(macro)를 정의하는 방법에 대해서 알아보겠다. 매크로는 함수와 외형 및 동작하는 방식이 비슷해 보이지만 내부적으로는 크게 다른 방식으로 동작한다.
매크로는 #define문으로 정의되는데 프로그램 중간에서 정의된 이름을 만나면 해당하는 매크로 코드로 치환된다. 예를 들어서 다음과 같이 매크로를 정의한다.
#define pow3(x) x*x*x |
이제 프로그램 중간에 pow3(2) 라고 쓰면 그 명령어가 통채로 2*2*2으로 대체되게 된다. 만약 pow(iA)라고 쓰면 iA*iA*iA로 바뀐다. 외형상 2이라는 숫자나 iA와 같은 변수를 매크로에 x로 인자로 넘길 수 있게 되므로 마치 함수 같아 보이지만 동작 방식은 전혀 다른 것이다.
#include <stdio.h>#define pow3(x) x*x*xint main() {int iA = 5;float fA = 1.5;printf("%d**3 = %d \n", 6, pow3(6)); //❶printf("%d**3 = %d \n", iA, pow3(iA)); //❷printf("%f**3 = %f \n", fA, pow3(fA)); //❸} |
6**3 = 2165**3 = 1251.500000**3 = 3.375000 |
여기서 ❶, ❷, ❸번 줄을 보면 매크로를 마치 함수를 호출하듯이 사용하고 있으나, 사실은 컴파일하기 전에 프로그램을 다음과 같이 단순 치환하여 변형한 것이 불과하다.
printf("%d^3 = %d \n", 6, 6*6*6 );printf("%d^3 = %d \n", iA, iA*iA*iA );printf("%f^3 = %f \n", fA, fA*fA*fA ); |
따라서 함수의 호출과는 동작하는 방식이 전혀 다른 것이다.
매크로의 인수로는 두 개 이상도 사용가능하다. 다음 예는 두 수들 중에서 작은 수를 찾아주는 매크로이다.
#include <stdio.h>#define MIN(a, b) (a<b)? a:bint main() {short nA = -10, nB = -15;printf("MIN(%d,%d) is %d.\n", 2, 3, MIN(2,3));printf("MIN(%d,%d) is %d.\n", nA, nB, MIN(nA, nB));} |
MIN(2,3) is 2.MIN(-10,-15) is -15. |
매크로는 단순치환이기 때문에 다음과 같은 경우를 주의해야 한다. 다음 예에서 세 숫자의 곱으로 치환하는 매크로를 예로 들어보았다.
#include <stdio.h>#define MUL1(a,b,c) a*b*c //❶#define MUL2(a,b,c) (a)*(b)*(c) //❷int mulF(int, int, int);int main(void){short sA = 2, sB = 3, sC = 4, sD1, sD2, sDF;sD1 = MUL1(sA+1, sB, sC);//❸sD2 = MUL2(sA+1, sB, sC);//❹sDF = mulF(sA+1, sB, sC);printf("MUL1: %d*%d*%d = %d \n", sA+1, sB, sC, sD1);printf("MUL2: %d*%d*%d = %d \n", sA+1, sB, sC, sD2);printf("MulF: %d*%d*%d = %d \n", sA+1, sB, sC, sDF);}int mulF(int iA, int iB, int iC){return iA*iB*iC;} |
❶과 같이 매크로를 정의했다면 ❸은 다음과 같이 치환된다.
nD1 = nA+1 * nB * nC; |
따라서 의도하지 않은 엉뚱한 계산결과가 nD1변수에 저장되게 된다. 즉, 매크로는 정의된 그대로 치환을 하기 때문에 이와 같은 오류가 발생하는 것이다. 이를 방지하려면 ❷와 같이 각각의 인수에 괄호( )를 쳐주면 된다. 그러면 ❹는 다음과 같이 의도한 대로 치환된다.
nD2 = (nA+1) * (nB) * (nC); |
이로서 의도한 계산 결과를 얻을 수 있다. 전체 실행 결과는 다음과 같다.
MUL1: 3*3*4 = 14MUL2: 3*3*4 = 36MulF: 3*3*4 = 36 |
매크로는 함수로 작성하기에는 다소 간단한 기능을 구현하는데 자주 사용된다. 하지만 매크로를 사용할 때에는 위와 같이 문제가 발생할 소지가 있으므로 보통 인수로 사용하는 변수에는 괄호를 꼭 붙여서 사용해야함에 주의해야 한다.
C++ 강좌 전체 목록 >>>
'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글
6.3 포인터 연산 (덧셈, 뺄셈) (0) | 2015.05.18 |
---|---|
6.2 포인터 선언과 초기화 (0) | 2015.05.18 |
C++의 정적 변수(static variable) (0) | 2015.05.18 |
C++의 지역변수와 전역변수 (0) | 2015.05.18 |
C++에서 함수의 인자 전달 (0) | 2015.05.18 |