본문 바로가기
코스웨어/16년 스마트컨트롤러

2016-08-30_조재찬_스터디일지_C언어-선행처리기와 매크로 (2)

by 알 수 없는 사용자 2016. 8. 30.
728x90
반응형

조건부 컴파일(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;
}



Output:

1
20 + 10 = 30 





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

정의되었다면 컴파일 대상에 포함
정의되지 않았다면 선행처리기가 #ifdef~#endif 까지의 코드를 지움



#include <stdio.h> // #define ADD 1 #define MIN 0 // 정의 여부만 물으므로 값을 지정하지 않아도 상관없음 int main(void) { int num1 = 20; int num2 = 10; #ifdef ADD // 주석에 의해 정의되지 않은걸로 처리 printf("%d + %d = %d \n", num1, num2, num1+num2); #endif #ifdef MIN // 정의되어 있으므로 컴파일 대상에 포함 printf("%d - %d = %d \n", num1, num2, num1-num2); #endif return 0; }



Output:

1
20 - 10 = 10 




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


정의되지 않았다면 포함

정의되어있다면 선행처리기가 #ifndef~#endif 까지의 코드를 지움




#else의 삽입: #if, #ifdef, #ifdef에 해당 (#endif로 끝을 표시)


#if  

if문이 참이면 포함, 거짓이면 else문이 포함


1
2
3
4
5
6
7
8
9
10
11
12
13
#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;
}



Output:

1
매크로 상수 HIT_NUM은 현재 5입니다.




#elif의 삽입 : else if와 유사, #if에만 해당 


if~else if~else 구문과 동일 형태를 구성할 수 있다.


#if~#elif~#else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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는 문자열안(" ")에 치환될 수 없다.


1
2
3
4
5
6
7
8
9
#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"


위의 두 문장 선언은 같다.

둘 이상의 문자열 선언을 나란히 하면, 하나의 문자열 선언으로 인식


1
2
3
4
5
6
7
8
9
#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))

최선의 해결책인듯 하지만...


1
2
3
4
5
6
7
8
9
10
11
#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;
}

Output:

1
2
학번: 1065175 
학번: 1065061 


위와 같이 0이 8진수를 의미하는 걸로 인식되어서 원하던 결과를 얻을 수 없다.



필요한 형태대로 단순 결합 : ## 연산자


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


int num = CON(22, 77); -> 220077



#define STNUM(Y, S, P) Y ## S ## P

YSP가 단순 결합됨


1
2
3
4
5
6
7
8
9
#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;
}



Output:

1
2
학번: 1065175 
학번: 1065075 


728x90