본문 바로가기
[C language] C 언어

c언어 총정리9 - 매크로 선행처리기 - 사용 방법, 잘못된 매크로

by codeomni 2023. 9. 1.
반응형

 

선행처리기

 

컴파일 이전에 처리로 선행처리기가 역할을 담당한다.

삽입해 놓은 선행처리 명령문대로 소스코드의 일부를 수정한다.

#으로 시작하고, 명령문 끝에 ;(세미콜론)을 붙이지 않는다.

 


매크로

 

코드를 작성할 때 특정한 텍스트 조각을 대체하는 간단한 코드 조각이다.

크기가 작은 함수와 호출 빈도수가 높은 함수를 매크로로 정의한다.

 

장점 - 일반 함수에 비해 실행 속도가 빠르다. 자료형에 따라서 별도로 함수를 정의x

단점 - 정의가 어렵다. 디버깅이 어렵다.

 


#define: Object-like macro

 

1
2
#define PI 3.1415
// (지시자) (매크로 이름) (매크로 몸체)

 

매크로를 마지막에 등장하는 매크로 몸체로 치환한다.

매크로의 이름은 대문자로 정의하는 것이 일반적이다.

 

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
#define NAME "codeomni"
 
int main(void)
{
    printf("이름: %s \n", NAME);
 
    return 0;
}

 

매크로 NAME을 매크로 몸체 "codeomni"로 치환한다.

 


#define: Function-like macro

 

매크로는 매개변수가 존재하는 형태도 사용한다.

매크로 함수로 동작방식이 함수와 유사하기 때문에 "함수와 유사한 매크로(function-like macro)"이다.

 

1
2
#define SQUARE(X) X*X
// (지시자) (매크로이름(매개변수)) (코드(매개변수))

 

매크로 이름의 패턴 등장하면, 코드의 유형으로 변경한다.

선행처리기에 의해서 변환되는 과정 자체를 매크로 확장(macro expansion)이라고 한다.

 


매크로 개행

 

1
2
#define SQUARE(X) \
        ((X)*(X))

 

가독성을 위해 여러 행으로 매크로를 정의한다.

\ 문자를 사용해서 줄이 개행되었음을 명시한다.

 


정의된 매크로 사용

 

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
#define TWO 2
#define MUL(X) ((X)*(TWO))
 
int main(void)
{
    printf("2를 곱한 값: %d \n", MUL(1024));
    return 0;
}

 

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

 


잘못된 매크로 정의

 

1
2
3
4
5
6
7
8
#include <stdio.h>
#define SQUARE(X) X*X
 
int main(void)
{
    printf("SQAURE of 3+2: %d \n", SQUARE(3+2));
    return 0;
}

 

함수는 3+2를 먼저 계산을 하지만, 선행처리기는 다르다.

매크로 내에서 매개변수를 여러 번 참조하는 경우,

괄호가 부족하면 연산자 우선순위에 문제가 발생한다.

 

1
2
3
4
5
6
7
8
#include <stdio.h>
#define SQUARE(X) ((X)*(X))
 
int main(void)
{
    printf("SQAURE of 3+2: %d \n", SQUARE(3+2));
    return 0;
}

 

해당 문제는 괄호로 처리가 가능하다.

매크로 함수를 정의할 때는 매크로의 몸체부분을 구성하는 전달인자를 괄호를 해주고,

마지막에 전체를 괄호로 묶어줘야 한다.

 


#in... #endif 참이면

 

조건부 코드 삽입을 위한 지시자이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#define X 1
#define Y 0
 
int main(void)
{
    int num1 = 2, num2=3;
 
#if X
    printf("%d + %d = %d \n", num1, num2, num1+num2);
#endif
 
#if Y
    printf("%d - %d = %d \n", num1, num2, num1+num2);
#endif
 
    return 0;
}

 

#if문 뒤에는 반드시 #endif문이 따른다.

#if 문이 참이면 #endif문 사이의 코드가 실행된다.

 


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

 

#ifdef는 매크로가 정의되었는지 여부를 기준으로 동작한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
// #define X 1
#define Y 1
 
int main(void)
{
    int num1 = 3, num2=2;
 
#ifdef X
    printf("%d + %d = %d \n", num1, num2, num1+num2);
#endif
 
#ifdef Y
    printf("%d - %d = %d \n", num1, num2, num1-num2);
#endif
 
    return 0;
}

 

#ifdef문은 매크로가 정의되어 있으면,

#endif 사이에 존재하는 소스코드가 실행된다.

 

1
#define Y

 

매크로의 값이 생략되어도 실행된다.


 

 

 

댓글