C의 전처리기 매크로는 코드의 이식성, 가독성 및 설정 용이성을 보장하기 위해 언어의 일환으로 등장했습니다. #define, #ifdef, #ifndef 지시어를 사용하면 조건부 코드 섹션을 만들고, 상수를 선언하며, 외부 파일을 포함할 수 있습니다 (#include).
문제의 역사:
전처리기 지시어는 서로 다른 시스템 및 컴파일러에 맞게 소스 코드를 쉽게 조정할 수 있도록 하고 반복적인 작업을 자동화하기 위해 도입되었습니다.
문제점:
전처리기가 없으면 플랫폼 차이로부터 추상화할 수 없고, 코드 조각을 반복하며, 헤더 파일의 이중 포함을 방지할 수 없습니다. 또한 매크로는 타입이 없고 유효 범위가 없기 때문에 주의가 필요합니다.
해결책:
상수 선언, 인라인 함수, 조건부 컴파일 및 헤더 파일의 다중 포함 방지를 위해 전처리기 매크로를 사용하는 것입니다.
코드 예:
#ifndef MY_HEADER_H #define MY_HEADER_H #define MAX_SIZE 100 #ifdef DEBUG #define LOG(x) printf("%s\n", x) #else #define LOG(x) #endif #endif /* MY_HEADER_H */
주요 특징:
헤더 파일에서 include guard를 잊어버리면 무엇이 발생하는가?
헤더 파일이 하나의 .c 파일에 여러 번 포함될 수 있으며 (다른 .h를 통해 암묵적으로), 이는 재정의 오류를 초래합니다.
#define 매크로와 인라인 함수 선언의 차이는 무엇인가?
#define는 텍스트를 단순히 대체하며 타입 및 구문 검사를 하지 않지만, 인라인 함수는 타입 분석 단계에서 컴파일러에 의해 검사가 이루어지는 일반 함수입니다.
매크로에 부작용이 있을 수 있는가?
네, 매크로가 부주의하게 정의되면 전달된 표현식이 여러 번 계산될 수 있습니다. 예를 들어:
#define SQUARE(x) (x) * (x) int a = SQUARE(++i); // ++i가 두 번 수행됩니다!
부모hesis 없이 부작용을 일으키는 매크로 사용:
#define DOUBLE(x) x + x int result = DOUBLE(1+2); // 결과가 6이 아니고 1+2+1+2=6? 아니다, 1+2+1+2=6 — 맞는가? 아니다, 결과는 1+2+1+2. // 실제로는 1 + 2 + 1 + 2 = 6이지만, DOUBLE(++i)인 경우 ++i는 두 번 적용됩니다.
장점:
단점:
부모hesis를 가진 매크로 정의 및 간단한 상수 사용:
#define DOUBLE(x) ((x) + (x)) #define BUFFER_SIZE 1024
장점:
단점: