매크로(macro)
- C 언어에서 전처리기(preprocessor)가 처리하는 기능으로, 프로그램 실행 전에 텍스트 치환으로 동작.
- C 언어에서는 #define 선행처리 지시문에 인수로 함수의 정의를 전달하여, 함수처럼 동작하는 매크로를 만들 수 있다.
- 매크로를 사용하면 코드의 재사용성과 가독성을 높이고, 반복적인 작업을 간단하게 처리할 수 있다.
매크로 함수의 장단점
👍 장점
1. 매크로 함수는 단순 치환만 해주므로, 인수의 타입을 신경쓰지 않는다.
2. 매크로 함수를 사용하면, 여러 개의 명령문을 동시에 포함할 수 있다.
3. 함수 호출에 의한 성능 저하가 일어나지 않으므로, 프로그램 실행 속도가 향상된다. (함수 호출과 달리, 런타임에 호출 비용이 없으므로)
👎 단점
1. 매크로는 단순 텍스트 치환이므로 연산자 우선순위를 명확히 지정하지 않으면 오류가 발생할 수 있다.
-> 따라서, 간단한 함수를 대체하는 데 좋다.
Ex1) 최대, 최소 정의
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
int main() {
int num1 = 20;
int num2 = 30;
int max_result = MAX(num1, num2);
int min_result = MIN(num1, num2);
printf("숫자 1: %d\n", num1); // 10
printf("숫자 2: %d\n", num2); // 30
printf("최댓값: %d\n", max_result); // 30
printf("최솟값: %d\n", min_result); // 20
return 0;
}
단! 매크로 함수는 일반 함수와 달리 '단순 치환'만 하므로, 일반 함수와 완전히 같은 방식으로 동작하진 않는다.
그로 이한 몇 가지 예시를 살펴보자. (Ex2- ①, ②)
EX2 - ①) 합/ 차 정의
#include <stdio.h>
#define ADD(a, b) a+b
#define SUBTRACT(a, b) ((a)-(b))
int main() {
int num1 = 20;
int num2 = 10;
int sum_result = ADD(num1, num2) * 2;
int diff_result = SUBTRACT(num1, num2);
printf("숫자 1: %d\n", num1); // 20
printf("숫자 2: %d\n", num2); // 10
printf("덧셈 결과: %d\n", sum_result); // 40
printf("뺄셈 결과: %d\n", diff_result); // 10
return 0;
}
Ex2 - ②) 합/ 차 정의
#include <stdio.h>
// 괄호를 과도하게 쳐서, function처럼 동작할 수 있도록 해야한다.
#define ADD(a, b) (a+b)
#define SUBTRACT(a, b) ((a)-(b))
int main() {
int num1 = 20;
int num2 = 10;
int sum_result = ADD(num1, num2) * 2;
int diff_result = SUBTRACT(num1, num2);
printf("숫자 1: %d\n", num1); // 20
printf("숫자 2: %d\n", num2); // 10
printf("덧셈 결과: %d\n", sum_result); // 60
printf("뺄셈 결과: %d\n", diff_result); // 10
return 0;
}
Ex1, Ex2는 다르게 동작된다.
매크로를 작성할 때에는, 괄호를 적절히 쳐 function처럼 동작할 수 있도록 해야한다.
왜냐하면,
Ex1에서는 int sum_result = (num1 + num2) * 2;
로 동작하기 때문에, (20 + 10) * 2 = 60
Ex2에서는 int sum_result = num1 + num2 * 2;
로 동작하기 때문에, 20 + 10 * 2 = 40
Ex3)
#define SET_BIT(var, pos) ((var)|= (1 << (pos)))
#define CLEAR_BIT(var, pos) ((var) &= ~(1 << (pos)))
#define TOGGLE_BIT(var, pos) ((var) ^= (1 << (pos)))
매크로 함수는 일반 함수와 비슷해보이지만, 일반 함수와는 전혀 다른 시간대에 이루어지는 과정임을 기억!
#include <stdio.h>와 #include "stdint.h"의 차이
헤더 파일의 목적과 포함 경로에 따라 다르다.
#include <stdio.h>
#include "stdint.h"
int main() {
int temp = print();
uint8_t temp2;
printf("%d\n",temp);
}
- #include <header>:
- 컴파일러는 표준 라이브러리 경로에서 헤더 파일을 찾는다.
- 주로 표준 헤더 파일을 포함할 때 사용합니다.
- 예: <stdio.h>, <stdint.h>.
- #include "header":
- 컴파일러는 현재 디렉토리에서 먼저 헤더 파일을 찾고, 없으면 표준 라이브러리 경로를 검색한다.
- 주로 사용자 정의 헤더 파일을 포함할 때 사용합니다.
조건부 컴파일
- 조건부 컴파일은 C 언어의 전처리기 지시자를 사용하여 특정 조건에 따라 소스 코드를 포함하거나 제외하는 기능
- 코드의 일부를 컴파일하거나 무시하여 코드의 가독성, 유지보수성, 플랫폼별 코드 작성 등을 지원
1. #if
- c언어의 if 조건문과 비슷
- 단, #endif 지시자를 사용하여 반드시 조건부 컴파일의 끝을 명시해야 한다.
#if 조건식1
컴파일할 명령문1
#elif 조건식2
컴파일할 명령문2
#else
컴파일할 명령문3
#endif
2. #ifdef
- 중복 선언의 가능성을 줄인다. = 'if defined'
- #ifdef 지시자 다음으로 매크로 이름과 같은 이름의 매크로가 이미 정의되어 있으면, 컴파일할 명령문 1이 컴파일
- 정의되어 있지 않으면, 컴파일할 명령문1이 컴파일되지 않고 넘어간다.
- #elif, #else 지시자를 사용하여 컴파일 조건을 확장할 수 있다.
#ifdef 매크로이름
컴파일할 명령문1
#elif 조건식
컴파일할 명령문2
#else
컴파일할 명령문3
#endif
3. #ifndef
- 'if not defined'
- #ifndef 지시자 다음에 나오는 매크로 이름과 같은 이름의 매크로가 앞서 정의되어 있지 않으면, 컴파일할 명령문1이 컴파일
- 정의되어 있으면, 컴파일할 명령문 1은 컴파일되지 않고 넘어간다.
- 2와 마찬가지로 #elif, #else 지시자를 사용하여 컴파일 조건을 확장할 수 있다.
#ifndef 매크로이름
컴파일할 명령문1
#elif 조건식
컴파일할 명령문2
#else
컴파일할 명령문3
#endif
예시
#include <stdio.h>
// 조건부 컴파일을 위한 매크로 정의
#define FEATURE_A
int main() {
// FEATURE_A 매크로가 정의되어 있는 경우에만 해당 코드 블록이 컴파일됩니다.
#ifdef FEATURE_A
printf("이 코드는 FEATURE_A가 정의되어 있을 때만 컴파일됩니다.\n");
#else
printf("이 코드는 FEATURE_A가 정의되어 있지 않을 때만 컴파일됩니다.\n");
#endif
// 다른 조건부 컴파일 예제
#ifndef FEATURE_B
printf("이 코드는 FEATURE_B가 정의되어 있지 않을 때만 컴파일됩니다.\n");
#endif
// 두 개 이상의 조건을 조합하는 경우
#if defined(FEATURE_A) && !defined(FEATURE_C)
printf("이 코드는 FEATURE_A가 정의되어 있고 FEATURE_C가 정의되어 있지 않을 때만 컴파일됩니다.\n");
#endif
return 0;
}
실행결과
이 코드는 FEATURE_A가 정의되어 있을 때만 컴파일됩니다.
이 코드는 FEATURE_B가 정의되어 있지 않을 때만 컴파일됩니다.
이 코드는 FEATURE_A가 정의되어 있고 FEATURE_C가 정의되어 있지 않을 때만 컴파일됩니다.
'IVS > C 프로그래밍' 카테고리의 다른 글
[C] 로또 추첨 예제 (1) | 2025.01.13 |
---|---|
[C] 함수 포인터 (0) | 2025.01.13 |
[C] 공용체(union), 열거체(enum) (0) | 2025.01.13 |
[C] 지역변수(local), 전역변수(global), 정적변수(static) (1) | 2025.01.13 |
[C] 구조체 - 바이트 패딩(Byte Padding) (1) | 2025.01.13 |