DEV Community

Resister-boy
Resister-boy

Posted on • Edited on

또 하나의 추상화 계층 - macro

매크로(macro)는 무엇일까?

매크로(Macro)는 특정 코드(자주 사용하는)를 하나의 명령어로 묶어 코드를 더 단순하고 간결하게 작성할 수 있도록 하는 문법이다. 매크로는 코드의 가독성을 높여줄 뿐만 아니라 매크로를 수정하면 소스 코드 전체에 수정된 내용이 반영되기 때문에 유지보수 측면에서 효율적이다.

매크로(macro) 정의하기

매크로는 #define을 사용하여 정의하며 일반적으로 소스 코드의 제일 상단에 위치한다. 이는 C 컴파일러가 소스 파일의 상단에서부터 컴파일하는데, 만일 매크로가 정의되기 이전에 사용될 경우 에러가 발생하기 때문이다.

또한 매크로를 선언할 때는 보통 대문자로 선언하는데 이는 코드의 가독성 때문이다. 매크로는 #define 이후 정의되는 명령어에 따라 매크로 상수와 매크로 함수로 구분되며, 매크로 상수와 매크로 함수는 아래와 같이 정의한다.

매크로(macro) 상수

매크로(macro)로 상수는 const 전역 변수와 비슷한 역할을 한다. 다만, 차이점은 매크로 상수는 컴파일러가 소스 코드를 컴파일 하기 전, 전처리 과정에서 매크로로 선언된 값이 소스 코드에서 매크로가 사용된 위치로 치환된다는 것이다. 또한 메크로 상수는 메모리가 할당되지 않는 반면, const 전역 변수는 데이터 영역에 메모리가 할당된다.

// #define [매크로 상수명] [값]
#define AGE 22 
#define NAME "Resister_boy"
#define WEIGHT 90

int main() {
    printf("My Age is %d\n", AGE); // AGE는 전처리 과정에서 22로 치환
    printf("My Name is %s\n", NAME); // NAME은 전처리 과정에서 Resister_boy로 치환
    printf("My Weight is %d\n", WEIGHT); // WEIGHT은 전처리 과정에서 90으로 치환
    return (0);
}
Enter fullscreen mode Exit fullscreen mode

매크로(macro) 함수

매크로(macro) 함수는 매크로(macro) 상수와 마찬가지로 컴파일 이전, 전처리 단계에서 치환되는 방식으로 동작한다. 사용 시 유의해야 할 점은 매크로 상수와는 달리, 매크로 함수에서는 여러 연산이 적용될 수 있는데, 이때 연산자 우선순위와 같은 규칙이 없기 때문에 괄호를 통해 우선순위를 명시해주어야 한다.

또한 매크로(macro) 함수는 코드를 연산하는 것이 아니라 단순히 치환만 해주는 것이기 때문에 인수의 타입을 체크하지 않으며, 동시에 여러 개의 명령문을 포함할 수 있다. 함수를 호출하는 과정에서 성능 저하가 일어나지 않기 때문에 실행속도가 향상된다는 장점이 있지만, 다만, 복잡한 함수의 구현과 디버깅이 어려우며, 추상화된 계층이 하나 더 생겨나는 것이기 때문에 코드를 읽고 이해하기 까다롭다는 단점이 있습니다.

// #define [매크로 함수명[인자]] [명령어]
#include <stdio.h> // 매크로에서 표준함수를 사용하려면 해당 함수원형이 선언된 헤더파일을 선언해야 한다
#define PLUS(X) ((X)+(X))
#define MINUS(Y) ((Y)-(Y))
#define MULTIPLY(Z) ((Z)*(Z))
#define PRINTVALUE(X, Y, Z) printf("PLUS : %d\nMINUS : %d\nMULTIPLY : %d", X, Y, Z);

int main(void) {
    int x = 1;
    int y = 5;
    int z = 10;

    int _x;
    int _y;
    int _z;

    _x = PLUS(x);
    _y = MINUS(y);
    _z = MULTIPLY(z);

    PRINTVALUE(_x, _y, _z);
    return (0);
}
Enter fullscreen mode Exit fullscreen mode

조건부 매크로(macro) 정의

#define이 무조건적으로 매크로를 선언하는 반면, 조건에 따라 매크로를 선언할 수 있도록 하는 명령어도 있다. 이 경우 조건에 해당하지 않을 경우 매크로가 컴파일되지 않으며, 이는 소스 자체가 존재하지 않는 것과 같다. 이를 전처리기라고 한다.

#if

오른쪽 조건이 참일 경우 아래 명령어를 컴파일합니다

#if NUMBER <= 10
   printf("%d\n", NUMBER) // NUMBER가 10이하일 때 NUMBER를 출력
Enter fullscreen mode Exit fullscreen mode

#elif

오른쪽 조건이 참일 경우 아래 명령어를 컴파일합니다

#elif NUMBER >= 20
   printf("%d\n", NUMBER) // NUMBER가 20이상일 때 NUMBER를 출력
Enter fullscreen mode Exit fullscreen mode

#else

#if 또는 #elif가 참이 아닐 경우 아래 명령어를 컴파일합니다

#else
   printf("%d\n", NUMBER) // NUMBER가 11이상이고 20미만일 때 NUMBER를 출력
Enter fullscreen mode Exit fullscreen mode

#ifdef

오른쪽 매크로 또는 파일이 정의되어 있을 경우 아래 명령어를 컴파일합니다

#ifdef NUMBER
   printf("%d\n", NUMBER) // NUMBER가 정의되어 있을 경우 NUMBER를 출력
Enter fullscreen mode Exit fullscreen mode

#ifndef

오른쪽 매크로 또는 파일이 정의되어 있지 않을 경우 아래 명령어를 컴파일합니다

#ifndef NUMBER
#define NUMBER 10 // NUMBER가 정의되어 있지 않을 경우 아래 NUMBER 10을 선언
Enter fullscreen mode Exit fullscreen mode

#endif

전처리 명령어가 끝났음을 정의하는 명령어입니다.

#endif
Enter fullscreen mode Exit fullscreen mode

매크로 정의 해제

#undef

전처리 명령어를 통해 정의한 매크로를 해제할 수 있습니다.

#undef NUMBER
Enter fullscreen mode Exit fullscreen mode

Top comments (0)