使用 C 宏调用关联*函数

标签 c macros c-preprocessor

*不要与关联数组混淆。

我知道如何使用宏对 C 中的函数进行矢量化,以提供类似于 Mathematica 的映射(或应用)功能的结果。即,将函数应用于参数列表。

#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] );                         \
}                     

然后我可以做类似的事情

#define FreeAllAtOnce(...) Apply( void, free, __VA_ARGS__ );

效果是

free( Array1 );
free( Array2 );
free( Array3 );

相当于

FreeAllAtOnce( Array1, Array2, Array3 );

这不是我编造的,我在一本书中读到过它,并且从那以后就大量使用它。

我的问题是:我可以做一些类似于通过一些二元函数关联组合数组的事情吗?以 GCD 函数为例。我想要一个像这样的功能:

GCD_all( a, b, c, d, e );

效果与

相同
GCD( GCD( GCD( GCD( a, b ), c ), d ), e );

对于任意数量的参数。

我已经尝试过这样做,但无法正常工作。我也对可能有其他参数传递给函数的情况感兴趣。在最一般的意义上,我希望使用以下函数来实现这一点:

Atype BinaryCombine( Atype a, Atype b, OtherType z, OtherType y )

这样我就有了一个功能

Atype BinaryCombineAll( Atype a, Atype b, Atype c, Atype d, OtherType z, OtherType y )

我希望这是有道理的。任何想法或帮助将不胜感激!

谢谢。

最佳答案

这需要相当棘手的机制(请参阅 answer 了解更多详细信息),因为您通常不能在 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);
}

gcc -E 产生如下输出:

int main(void)
{
  GCD(GCD(GCD(GCD(a, b), c), d), e);
}

NUM_ARGS 自动查找参数的数量。通过这种方式,您可以获得“起点”宏GCD_OF_N,以便进一步扩展。

关于使用 C 宏调用关联*函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37862280/

相关文章:

c - 传递给接受 char 参数的函数时打印 int 的实际值

c - 打印 EOF 值的预期程序

xslt - 祖先或 self 不会选择 self

c++ - 从整数转换为指针

c - #在C中定义一个输入数字

c - 如何使用 lxdialog 创建 GUI(例如 menuconfig)

c - 当进程仍在运行时如何重新启动处理

gcc - 检测预处理器中的 ARM NEON 可用性?

json - 将 Vim 宏应用于多行

在编译时创建函数列表