매크로
장점
1. 매크로 함수는 단순 치환, 타입을 고려하지 않는다.
2. 매크로 함수를 사용하면 여러 개의 명령문을 동시에 포함할 수 있다.
3. 함수 호출에 의한 성능 저하가 일어나지 않으므로, 프로그램의 실행속도가 향상된다.
단점
1. 원하는 결과를 얻는 정확한 매크로 함수의 구현은 어려우며, 따라서 디버깅 또한 매우 어렵습니다.
2. 매크로 함수의 크기가 증가하면 증가할수록 사용되는 괄호 또한 매우 많아져서 가독성이 떨어집니다.
매크로 정의
- #define 매크로이름 값
- #undef 매크로이름
#include <stdio.h>
#define COUNT 10 // 10을 COUNT로 정의
int main()
{
printf("%d\n", COUNT); // 10
#undef COUNT // 앞에서 정의한 COUNT 해제
#define COUNT 20 // 20을 COUNT로 정의
printf("%d\n", COUNT); // 20
return 0;
}
매크로 함수(function-like macro)
- #define 매크로이름(x) 함수(x)
- #define 매크로이름(x) 코드조합
#include <stdio.h>
#define PRINT_NUM(x) printf("%d\n", x)
#define PRINT_NUM3(x) printf("%d\n", x); \
printf("%d\n", x + 1); \
printf("%d\n", x + 2);
int main()
{
PRINT_NUM(10); // 10: printf("%d\n", 10)
PRINT_NUM(20); // 20: printf("%d\n", 20)
PRINT_NUM3(10); // 10
// 11
// 12
return 0;
}
Swap 예제
두 값을 교환하는 구조
두 값을 교환하는 매크로 함수 구현
실행시 매크로가 치환된 형태
매크로 주의점
1. 제어 구조
2. 연산자 우선순위
#include <stdio.h>
#define SQR1(X) X*X
#define SQR2(X) ((X)*(X))
#define PRT(X) printf("계산 결과는 %d입니다.\n", X)
int main(void)
{
int result;
int x = 5;
result = SQR1(x+3); // x+3*x+3 = 5+3*5+3 = 23
PRT(result); // 계산 결과는 23입니다.
result = SQR2(x+3);
PRT(result); //계산 결과는 64입니다.
return 0;
}
# 연산자
: 큰따옴표("")를 포함해 그대로 문자열 상수로 변환
#include <stdio.h>
#define SQR(X) printf(""#X"의 제곱은 %d입니다.\n", ((X)*(X)))
int main(void)
{
int x = 5;
SQR(x); // x의 제곱은 25입니다.
SQR(3+4); // 3+4의 제곱은 49입니다.
return 0;
}
## 연산자
: ## 연산자는 두 개의 토큰을 하나의 토큰으로 결합, 변수나 함수의 이름을 프로그램의 런타임에 정의
#include <stdio.h>
#define XN(n) x ## n //변수의 이름을 동적으로 정의. xn 형태가 된다
#define PRT_XN(n) printf("x"#n"에 저장된 값은 %d입니다.\n", x ## n)
int main(void)
{
int XN(1) = 10; // x1 = 10
int XN(2) = 20; // x2 = 20
printf("x1에 저장된 값은 %d입니다.\n", x1);
printf("x2에 저장된 값은 %d입니다.\n", x2);
PRT_XN(1); // x1에 저장된 값은 10입니다.
PRT_XN(2); // x2에 저장된 값은 20입니다.
return 0;
}
미리 정의된 매크로(predefined macro)
__DATE__ | 선행처리가 수행된 날짜를 "Mmm dd yyyy"형식으로 나타낸 문자열 |
__TIME__ | 선행처리가 수행된 시간을 "hh:mm:ss"형식으로 나타낸 문자열 |
__FILE__ | 현재 소스 파일의 이름을 나타내는 문자열 |
__LINE__ | 현재 소스 파일에서 처리중인 라인 번호를 나타내는 문자열 |
__STDC__ | 컴파일러가 C언어 표준을 따르면 1로 설정함. |
__STDC_HOSTED__ | 호스트 환경이 아니면 0, 호스트 환경이면 1로 설정함. |
#include <stdio.h>
int main(void)
{
printf("선행처리가 수행된 날짜는 %s입니다.\n", __DATE__);
printf("선행처리가 수행된 시간은 %s입니다.\n", __TIME__);
printf("현재 소스 파일에서 처리중인 라인 번호는 %d입니다.\n", __LINE__);
printf("__STDC__ : %d\n", __STDC__);
printf("__STDC_HOSTED__ : %d\n", __STDC_HOSTED__);
return 0;
}
/* 선행처리가 수행된 날짜는 Feb 15 2017입니다.
선행처리가 수행된 시간은 17:03:55입니다.
현재 소스 파일에서 처리중인 라인 번호는 7입니다.
__STDC__ : 1
__STDC_HOSTED__ : 1 */