amc*_*lde 8 c macros c-preprocessor
*不要与与关联阵列有任何关系混淆.
我知道如何使用宏来向量化C中的函数,以提供类似于Mathematica的Map(或Apply)功能的结果.即将函数应用于参数列表.
#define Apply( type, function, ...) \
{ \
void *Stop = (int[]){0}; \
type **List = (type*[]){__VA_ARGS__, Stop}; \
for( int i = 0; List[i] != Stop; ++i ) \
function( List[i] ); \
}
Run Code Online (Sandbox Code Playgroud)
然后我可以做类似的事情
#define FreeAllAtOnce(...) Apply( void, free, __VA_ARGS__ );
Run Code Online (Sandbox Code Playgroud)
这有效果
free( Array1 );
free( Array2 );
free( Array3 );
Run Code Online (Sandbox Code Playgroud)
相当于
FreeAllAtOnce( Array1, Array2, Array3 );
Run Code Online (Sandbox Code Playgroud)
我没有说明这一点,我在一本书中读到了它并且从那以后大量使用它.
我的问题是:我可以做类似的事情通过一些二进制函数关联组合一个数组.例如,采用GCD功能.我想要一个像这样的功能:
GCD_all( a, b, c, d, e );
Run Code Online (Sandbox Code Playgroud)
这与效果相同
GCD( GCD( GCD( GCD( a, b ), c ), d ), e );
Run Code Online (Sandbox Code Playgroud)
对于任何数量的论点.
我试图做到这一点并且无法使其正常工作.我也对可能有其他参数传递给函数的情况感兴趣.在最通用的意义上,我希望通过以下功能来实现这一点:
Atype BinaryCombine( Atype a, Atype b, OtherType z, OtherType y )
Run Code Online (Sandbox Code Playgroud)
所以我有一个功能
Atype BinaryCombineAll( Atype a, Atype b, Atype c, Atype d, OtherType z, OtherType y )
Run Code Online (Sandbox Code Playgroud)
我希望这是有道理的.任何想法或帮助将非常感谢!
谢谢.
这需要相当棘手的机制(有关更多详细信息,请参阅此答案),因为通常不能在 C 中使用递归宏:
#define _NUM_ARGS2(X,X5,X4,X3,X2,X1,N,...) N
#define NUM_ARGS(...) _NUM_ARGS2(0,__VA_ARGS__,5,4,3,2,1,0)
// be sure to add X6,X7,... and 6,7,... to support more arguments
#define GCD_OF_1(a) (a)
#define GCD_OF_2(a,b) GCD(a, b)
#define GCD_OF_3(a,b,...) GCD_OF_2(GCD_OF_2(a,b),__VA_ARGS__)
#define GCD_OF_4(a,b,...) GCD_OF_3(GCD_OF_2(a,b),__VA_ARGS__)
#define GCD_OF_5(a,b,...) GCD_OF_4(GCD_OF_2(a,b),__VA_ARGS__)
// in general:
// #define GCD_OF_N(a,b,...) GCD_OF_N-1(GCD_OF_2(a,b),__VA_ARGS__)
#define _GCD_OF_N3(N, ...) GCD_OF_ ## N(__VA_ARGS__)
#define _GCD_OF_N2(N, ...) _GCD_OF_N3(N, __VA_ARGS__) // helper macro to expand N
#define GCD_all(...) _GCD_OF_N2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__)
int main(void)
{
GCD_all(a, b, c, d, e);
}
Run Code Online (Sandbox Code Playgroud)
产生gcc -E的输出为:
int main(void)
{
GCD(GCD(GCD(GCD(a, b), c), d), e);
}
Run Code Online (Sandbox Code Playgroud)
自动NUM_ARGS查找参数的数量。这样您就获得了GCD_OF_N进一步扩展的“起点”宏。