선행처리는 컴파일이전의 처리를 의미한다


#define PI 3.14 // 컴파일시 PI 를 만나면 3.14로 치환 

선행처리기에 의해서 처리되는 문장은 명령문의끝에 세미콜론을 붙이지 않는다

이때 , #difine을 지시자 , PI 를 매크로 , 3.14를 매크로 몸체라고한다. // 매크로를 매크로몸체로 치환! , 매크로는 대문자로 정의하는것이 일반적.


매크로 함수


#difine SQUARE(X) X*X 

매크로이름에 등장하는 괄호안의존재 X는 정해지지않은 임의의 값을 의미한다. 

선행처리기는 연산을 순서대로 처리하는것이 아니라 , 그 값을 바꾸는것이기 때문에 , SQUARE (3+2)는 3+2*3+2로 치환되어 11값이나타나게된다 따라서 , SQUARE(X) (X)*(X)로 치환해주는게 좋다. 이와같이 120/SQUARE(2) 또한 120/4 가아닌120/2*2로 치환되기때문에 , SQUARE((X)*(X))로 선언해줘야한다.

매크로 함수를 선언할때는 괄호를 자주 사용하는것이좋다.

매크로를 두줄에선언할때는 \ 문자를 이용해서 선언한다


#define SQUARE (X)   \

     ((X)*(X))


매크로 정의시 먼저 정의된 매크로도 사용 가능하다.

#define CIRCLE_AREA(R) ((SQUARE(R))*(PI))


매크로 함수의 장점


매크로함수는 일반 함수에 비해 실행속도가 빠르다

자료형에 따라서 별도로 함수를 정의하지않아도된다


매크로 함수의 단점


정의하기가 까다롭다

디버깅하기 쉽지않다.


매크로로 정의하면 좋은함수


작은크기의 함수

호출의 빈도수가 높은 함수


조건부 컴파일을 위한 매크로


#if... #endif : 참이라면


#define ADD 1

#if ADD // ADD가 참이라면 밑의코드 컴파일( ADD가 1로 참이므로 컴파일 )

 #endif // ADD가 거짓이라면 여기까지 코드를 컴파일에서 배제함.


#ifdef ... #endif : 정의되었다면


#define ADD 0

#if ADD // ADD가 정의되었다면 밑의코드 컴파일 (ADD가 0으로 거짓이어도 컴파일)

#endif // ADD가 정의되지않았다면 여기까지 코드를 컴파일에서 배제함


#ifndef ... #endif : 정의되지않았다면


//define ADD 0

#if ADD // ADD가 정의되지않았다면 밑의코드 컴파일 (ADD가 0으로 거짓이어도 컴파일)

#endif // ADD가 정의되지않았다면 여기까지 코드를 컴파일에서 배제함


#else문의 삽입 , #elif문의 삽입


#define HIT_NUM 7


#if HIT_NUM == 5 //조건식 사용가능!

puts ("매크로 상수는 5입니다!");

#elif HIT_NUM == 6 

puts ("매크로 상수는 6입니다!");

#else 

puts("매크로상수는 5,6이 아닙니다!");

#endif


매개변수의 결합과 문자열화


문자열 내에서는 매크로의 매개변수 치환이 발생하지않기때문에 , 문자열내의 매개변수를 치환하고싶다면 #연산자를 사용해야한다.

#연산자는 치환의 결과를 문자열로 구성하는 연산자이다.

#define STR(A,B) "#A의 직업은 #B입니다" // 11,12 입력시 "11의 직업은 12입니다"(11, 12도 문자열로변환)


문자열을 나란히 선언하면 하나의 문자열이 된다


char * str = "abc""def"; // str엔 "abcdef" 저장

char * str = STR(ABC) STR(DEF); //str에 "ABCEDF" 저장


필요한 형태대로 단순하게 결합하기 : ##연산자 ( 문자열로 치환하지않고 )


이연산자는 매크로함수의 전달인자를 다른대상 (전달인자 , 숫자 , 문자 , 문자열등 ) 과 이어줄때 사용한다,


#define CON(UPP , LOW) UPP ## 00 ## LOW

int num = CON(22.33) // num에는 220033이 저장된다




+ Recent posts