조건부 컴파일(Conditional Compilation)을 위한 매크로
#if... #endif : 참이라면
조건부 코드 삽입을 위한 지시자
참이면 #if~#endif 까지 컴파일 대상에 포함
거짓이면 선행처리기가 #if~#endif 까지의 코드를 지움
#include <stdio.h>
#define ADD 1 // 0이 아닌 값은 참
#define MIN 0 // 0은 거짓
int main(void)
{
int num1 = 20;
int num2 = 10;
#if ADD // ADD가 '참'이라면
printf("%d + %d = %d \n", num1, num2, num1+num2);
#endif
#if MIN // MIN이 '참'이라면
printf("%d - %d = %d \n", num1, num2, num1-num2);
#endif
return 0;
}
|
20 + 10 = 30 |
#ifdef... #endif : 정의되었다면
정의되었다면 컴파일 대상에 포함
정의되지 않았다면 선행처리기가 #ifdef~#endif 까지의 코드를 지움
|
20 - 10 = 10 |
#ifndef... #endif : 정의되지 않았다면
정의되지 않았다면 포함
정의되어있다면 선행처리기가 #ifndef~#endif 까지의 코드를 지움
#else의 삽입: #if, #ifdef, #ifdef에 해당 (#endif로 끝을 표시)
#if
if문이 참이면 포함, 거짓이면 else문이 포함
#include <stdio.h>
#define HIT_NUM 5
int main(void)
{
#if HIT_NUM==5 // if문이 참이면 컴파일 대상에 포함
puts("매크로 상수 HIT_NUM은 현재 5입니다.");
#else // if문이 참이 아닐 때 else문이 컴파일 대상으로 포함, 이 때 if문의 코드는 전처리기가 제거
puts("매크로 상수 HIT_NUM은 현재 5가 아닙니다.");
#endif // if문의 끝을 나타냄
return 0;
}
|
매크로 상수 HIT_NUM은 현재 5입니다. |
#elif의 삽입 : else if와 유사, #if에만 해당
if~else if~else 구문과 동일 형태를 구성할 수 있다.
#if~#elif~#else
#include <stdio.h>
#define HIT_NUM 7
int main(void)
{
#if HIT_NUM==5
puts("매크로 상수 HIT_NUM은 현재 5입니다.");
#elif HIT_NUM==6
puts("매크로 상수 HIT_NUM은 현재 6입니다.");
#elif HIT_NUM==7
puts("매크로 상수 HIT_NUM은 현재 7입니다.");
#else
puts("매크로 상수 HIT_NUM은 5, 6, 7은 확실히 아닙니다.");
#endif
return 0;
} |
Output :
매크로 상수 HIT_NUM은 현재 7입니다.
'매개변수'의 결합과 '문자열'화
문자열 내에서는 매크로의 매개변수 치환 불가
#define STRING_JOB(A, B) "A의 직업은 B입니다."
괄호안의 A와 B는 문자열안(" ")에 치환될 수 없다.
#include <stdio.h>
#define STRING_JOB(A, B) "A의 직업은 B입니다."
int main(void)
{
printf("%s \n", STRING_JOB(이동춘, 나무꾼));
printf("%s \n", STRING_JOB(한상순, 사냥꾼));
return 0;
} |
Output :
A의 직업은 B입니다.
A의 직업은 B입니다.
"이동춘의 직업은 나무꾼입니다."라는 문장을 기대하지만
"A의 직업은 B입니다."로 치환된다.
이를 해결하기 위해 #연산자를 이용
#define STR(ABC) #ABC
매개변수 ABC에 전달되는 인자를 문자열 "ABC"로 치환
예)
STR(123) "123"
STR(12, 23, 34) "12, 23, 34"
char * str = "ABC" "DEF";
char * str = "ABCDEF"
위의 두 문장 선언은 같다.
둘 이상의 문자열 선언을 나란히 하면, 하나의 문자열 선언으로 인식
#include <stdio.h>
#define STRING_JOB(A, B) #A"의 직업은 " #B"입니다."
int main(void)
{
printf("%s \n", STRING_JOB(이동춘, 나무꾼));
printf("%s \n", STRING_JOB(한상순, 사냥꾼));
return 0;
} |
Output :
이동춘의 직업은 나무꾼입니다.
한상순의 직업은 사냥꾼입니다.
매크로 연산자 없이 단순 연결은 불가능
10/65/175 -> 1065175
#define STNUM(Y, S, P) YSP
#define STNUM(Y, S, P) Y S P
위의 두 정의는 컴파일 에러
#define STNUM(Y, S, P) ((Y)*100000+(S)*1000+(P))
최선의 해결책인듯 하지만...
#include <stdio.h>
//#define STNUM(Y, S, P) YSP
//#define STNUM(Y, S, P) Y S P
#define STNUM(Y, S, P) ((Y)*100000+(S)*1000+(P))
int main(void)
{
printf("학번: %d \n", STNUM(10, 65, 175));
printf("학번: %d \n", STNUM(10, 65, 075));
return 0;
} |
위와 같이 0이 8진수를 의미하는 걸로 인식되어서 원하던 결과를 얻을 수 없다.
필요한 형태대로 단순 결합 : ## 연산자
#define CON(UPP, LOV) UPP ## 00 ## LOW
int num = CON(22, 77); -> 220077
#define STNUM(Y, S, P) Y ## S ## P
YSP가 단순 결합됨
#include <stdio.h>
#define STNUM(Y, S, P) Y##S##P
int main(void)
{
printf("학번: %d \n", STNUM(10, 65, 175));
printf("학번: %d \n", STNUM(10, 65, 075));
return 0;
}
|
'코스웨어 > 16년 스마트컨트롤러' 카테고리의 다른 글
2016-09-04_조재찬_스터디일지_C++기초 1 (데이터 입출력, 지역변수, 함수 오버로딩, default) (0) | 2016.09.03 |
---|---|
2016-09-02_조재찬_스터디일지_C언어-리스트에 구조체 변수 저장 (0) | 2016.09.02 |
2016-08-31_조재찬_스터디일지_C언어-순차(배열기반) 리스트 (0) | 2016.09.01 |
2016-08-31_조재찬_스터디일지_C언어-파일의 분할과 헤더파일의 디자인 (0) | 2016.08.31 |
2016-08-29_조재찬_스터디일지_C언어-선행처리기와 매크로 (0) | 2016.08.30 |
2016-08-28_조재찬_스터디일지_C언어-파일위치 지시자 / 메모리 관리와 동적할당 (0) | 2016.08.29 |
2016-08-25_조재찬_스터디일지_C언어-파일 입출력 (0) | 2016.08.25 |
2016-08-24_조재찬_스터디일지_C언어-구조체 (0) | 2016.08.25 |