[C]매크로 함수(mecro function)


이번 포스트는 매크로 함수(mecro function)에 관한 내용입니다.


1️⃣ 매크로함수

(1) 매크로함수의 기본사용

  • #define을 이용하여 함수처럼 사용할 수 있습니다.
  • 다른 매크로들과 마찬가지로 단순히 대체항목으로 복붙</b>을 해줍니다. (전처리 단계에서 해결)

< 매크로함수 예시 >

#include <stdio.h>

#define SQUARE(a) a * a
#define ADD(a, b) a + b
#define SUBTRACT(a, b) a - b

int main(void)
{
    printf("SQUARE(3): %d\n", SQUARE(3));
    printf("ADD(3, 4): %d\n", ADD(a, b));
    printf("SUBTRACT(7, 3): %d\n", SUBTRACT(7, 3));
}
/* 출력 */
SQUARE(3): 9
ADD(3, 4): 7
SUBTRACT(7, 3): 4
  • 매크로를 이용하면 한줄의 코드로 함수와 같이 동작하게 만들 수 있습니다.
  • 또한 전처리과정에서 처리를 하기 때문에 속도가 빠릅니다.
  • 하지만 매크로의 특성상 코드를 단순히 복사하기 때문에 복사된 후의 연산 우선순위를 고려해야 합니다.

< 매크로함수 실수할 수 있는 예시 >

#include <stdio.h>
#define ADD(a, b) a + b
#define ADD2(a, b) (a + b)  // 실수를 줄이는 습관(괄호 이용)

int main(void)
{
    int result1, result2;

    result1 = 10 * ADD(3, 4);
    result2 = 10 * ADD2(3, 4);

    printf("ADD: %d\n", result1);
    printf("ADD2: %d\n", result2);
}
/* 출력 */
ADD: 34
ADD2: 70
  • 위의 예시와 같이 매크로는 단순히 코드를 복사하기 때문에 괄호 ()를 사용하는 습관을 가져 실수를 줄여야 합니다.

(2) 매크로함수를 여러줄 작성하기

  • \를 이용하면 매크로를 여러 줄로 작성할 수 있습니다. mecro_function_example /* 출력 */
    3^4 = 81



(3) 매크로함수 활용

  • __builtin_trap();코드를 이용한 나만의 어서트매크로를 만들 수 있습니다.
  • assert()함수의 경우 실패시호출 스택(call stack)의 현재 위치assert()함수 속입니다.
  • 반면 __builtin_trap();은 문제가 생긴 부분에서 멈추기 때문에 위치를 정확히 알 수 있습니다. 즉, 호출 스택의 현재 위치가 어서트에 실패한 코드의 현 위치입니다. 그렇기 때문에 assert()함수보다 디버깅이 편합니다.
  • 또한 stderr출력을 이용하여 사람이 읽기 편하게 설명할 수 있습니다.

mecro_function_example2 /* 출력 */
invalid level(test.c: 13)

  • 하지만 __builtin_trap();(맥os기준)대신에 __asm { int 3};일 수도 있고 또 다를 수도 있습니다.
  • 플랫폼마다 사용하는 어셈블리 명령어가 달라집니다. (C언어가 크로스 플랫폼이라는 주장은 어셈블리어 코드(.s)로 바뀌기 전까지임을 기억해야 합니다.)


2️⃣ 전처리기 명령어

(1) # 명령어

  • ‘#’을 사용하면 #define의 매개변수 자체를 문자열로 바꿔줍니다.
#include <stdio.h>

#define STR(a) #a

int main(void)
{
    printf("%s\n", STR(\n));
    printf("%s\n", STR("\n"));
    printf("%s\n", STR(Hello));
    printf("%s\n", STR("Hello"));
}
/* 출력 */


"\n"
Hello
"Hello"
  • \(escape)문자도 자동으로 추가해줍니다.

(2) ## 명령어

  • 대체 목록안에 있는 두 단어를 합쳐서 새로운 텍스트로 바꿔줍니다.
#include <stdio.h>
#define P_ID(n) p_id_##n

int main(void)
{
    int p_id_me = 3;
    int p_id_mom = 4;
    int p_id_dad = 5;
    
    printf("%d\n", P_ID(me));
    printf("%d\n", P_ID(mom));
    printf("%d\n", P_ID(dad));
}
/* 출력 */
3
4
5




3️⃣ 매크로 함수를 이용해서 튜플 만들기

  • 이미 정해진 데이터라면 일리리 구조체를 만들어서 실행중에 출력하는 것은 비효율적입니다.
  • 그렇기 때문에 전처리기튜플을 만들어줘서 데이터를 한번에 대입시키는 방법을 쓰면 속도면에서 효율적입니다.

< 전처리기튜플 예시 >

mecro_tuple /* 출력 */
0: 철수, 24살
1: 영희, 32살
2: 민수, 19살
3: 지은, 25살




© 2021.02. by kirim

Powered by kkrim