>  기사  >  백엔드 개발  >  C에서 재귀 매크로를 어떻게 구현할 수 있나요?

C에서 재귀 매크로를 어떻게 구현할 수 있나요?

Barbara Streisand
Barbara Streisand원래의
2024-11-17 19:49:02135검색

How Can We Implement Recursive Macros in C?

매크로 인수에 대한 매크로 재귀 이해

C 프로그래밍에서 매크로는 텍스트 조작을 위한 강력한 도구를 제공합니다. 흥미로운 측면 중 하나는 다른 매크로의 인수에 대해 매크로를 사용할 수 있다는 것입니다. 그러나 일반적으로 언어에서는 재귀 매크로가 허용되지 않기 때문에 기술적인 문제가 발생합니다.

문제: 재귀 매크로

우리가 만들고자 하는 시나리오를 고려해보세요. 지정된 매크로 PRINT를 인수 목록에 적용하는 PRINT_ALL이라는 foreach 매크로. 예를 들면 다음과 같습니다.

int a = 1, b = 3, d = 0;
PRINT_ALL(a,b,d);

이렇게 하면 각 변수 a, b 및 d에 대해 PRINT 매크로가 호출됩니다. 순진한 접근 방식은 다음과 같이 재귀 매크로를 사용할 수 있습니다.

#define FIRST_ARG(arg,...) arg
#define AFTER_FIRST_ARG(arg,...) , ##__VA_ARGS__
#define PRINT(a) printf(#a": %d", a)
#define PRINT_ALL PRINT(FIRST_ARG(__VA_ARGS__)); PRINT_ALL(AFTER_FIRST_ARG(__VA_ARGS__))

그러나 이 접근 방식에는 두 가지 문제가 있습니다. 매크로는 자신을 재귀적으로 호출할 수 없으며 재귀를 중지하기 위한 중지 조건이 부족합니다.

재귀적 해결 방법

이러한 장애물을 극복하기 위한 영리한 해결 방법은 매크로 평가 재귀라는 기술을 활용하는 것입니다. 핵심 아이디어는 실제로 매크로 자체를 호출하지 않고 매크로 호출을 시뮬레이션하는 매크로 텍스트를 내보내는 것입니다.

다음 매크로를 고려하세요.

#define MAP_OUT

다음 매크로가 있는 경우:

#define A(x) x B MAP_OUT (x)
#define B(x) x A MAP_OUT (x)

매크로 A(blah)를 평가하면 출력 텍스트가 생성됩니다.

blah B (blah)

이 텍스트는 매크로 대체 자리 표시자 역할을 합니다. 추가 확장을 위해 전처리기로 다시 전달되어 매크로 평가 프로세스를 계속할 수 있습니다.

이 재귀를 용이하게 하기 위해 일련의 EVAL 매크로가 정의됩니다.

#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__)))
#define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL4(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL(...)EVAL4(EVAL4(EVAL4(__VA_ARGS__)))

각 매크로가 적용됩니다. 여러 수준의 평가를 통해 적용되는 매크로의 효과를 증폭시킵니다.

재귀 중지

재귀를 제어하기 위해 특수 매크로 MAP_END가 정의됩니다.

#define MAP_END(...)

이 매크로를 평가해도 아무런 효과가 없으며 효과적으로 재귀를 종료합니다.

다음 과제는 재귀를 계속하는 대신 MAP_END를 사용할 시기를 결정하는 것입니다. 이를 달성하기 위해 MAP_NEXT 매크로는 목록 항목을 특수 목록 끝 표시와 비교합니다. 일치하면 MAP_END를 반환합니다. 그렇지 않으면 다음 매개변수를 반환합니다.

#define MAP_GET_END() 0, MAP_END
#define MAP_NEXT0(item, next, ...) next MAP_OUT
#define MAP_NEXT1(item, next) MAP_NEXT0(item, next,0)
#define MAP_NEXT(item, next) MAP_NEXT1(MAP_GET_END item, next)

MAP_NEXT 매크로를 신중하게 구성하여 재귀가 계속될지 아니면 끝날지 제어할 수 있습니다.

최종 구현

이러한 구성 요소를 결합하면 목록을 반복하고 지정된 매크로를 각 항목에 적용하는 MAP 매크로를 만들 수 있습니다.

#define MAP(f,...)EVAL(MAP1(f,__VA_ARGS__,(),0))

이 매크로는 목록 끝 표시를 배치하여 작동합니다. ANSI 준수를 보장하기 위한 추가 인수와 함께 목록 끝에. 그런 다음 여러 EVAL 매크로 호출을 통해 목록을 전달하고 결과를 반환합니다.

이 기술은 매크로 인수에 매크로를 사용하는 문제에 대한 창의적인 솔루션을 제공합니다. 정교한 매크로 조작 기능을 지원하므로 프로그래머는 새로운 방식으로 전처리기의 기능을 확장할 수 있습니다.

위 내용은 C에서 재귀 매크로를 어떻게 구현할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.