我有一个 ansi C 函数,可以根据模式对数组中的值进行求和。像这样的东西:
long sum_all_according_to_pattern(int n, int *values, int *pattern)
{
long sum = 0;
int i = 0;
for(;i<n;i++){
if(pattern[i])
sum+=values[i];
}
return sum;
}
假设我有一组模式,例如:
模式 1:1,1,1,1
模式 2:1,1,0,0
模式 3:1,0,0,1
我需要为每个模式生成一个特定的代码,没有循环和 if。对于之前的模式,它将是:
long sum_according_to_pattern_1(int *values)
{
return values[0]+values[1]+values[2]+values[3];
}
long sum_according_to_pattern_2(int *values)
{
return values[0]+values[1];
}
long sum_according_to_pattern_3(int *values)
{
return values[0]+values[3];
}
甚至
long sum_according_to_pattern_1(int *values)
{
long sum = 0;
sum+=values[0];
sum+=values[1];
sum+=values[2];
sum+=values[3];
return sum;
}
long sum_according_to_pattern_2(int *values)
{
long sum = 0;
sum+=values[0];
sum+=values[1];
return sum;
}
long sum_according_to_pattern_3(int *values)
{
long sum = 0;
sum+=values[0];
sum+=values[3];
return sum;
}
现在,假设此类模式可以比仅 4 个元素大得多。另外,假设我拥有的不仅仅是这 3 种模式。
我的问题是:有什么方法可以仅使用 ansi C 结构来实现这一点吗?由于我试图保留所有内容,因此我不想编写脚本来为我生成代码。我需要的是使用位图宏之类的东西来指定模式,然后在编译时生成函数。
最佳答案
我的做法是使用一个宏来定义您想要的所有模式,并结合其他宏来定义您需要的函数或其他信息。所以你会得到类似的东西:
#define FUNCTION_PATTERNS(M) \
M(1, 0xf) \
M(2, 0x3) \
M(3, 0x9)
#define DEFINE_SUM_FUNCTION(NUM, PATTERN) \
long sum_according_to_pattern_##NUM(int *values) { \
long sum = 0; \
for (int i = 0; 1UL << i <= PATTERN; i++) \
if (PATTERN & (1UL << i)) sum += values[i]; \
}
#define SUM_FUNCTION_NAME(NUM, PATTERN) sum_according_to_pattern_##NUM
现在您可以轻松声明所有函数并构建指向它们的指针表:
FUNCTION_PATTERNS(DEFINE_SUM_FUNCTION)
long (*sum_functions[])(int *) = { FUNCTION_PATTERNS(SUM_FUNCTION_NAME) };
如果需要,您可以在 DEFINE_SUM_FUNCTION
宏中手动展开循环,或者您可以依靠 C 编译器来为您完成此操作,可能使用适当的编译指示或编译时标志。
请注意,上述内容最多只能处理 32 或 64 个元素(取决于架构)。如果您想要更多,则必须将模式拆分为多个值。
关于使用类似位图的宏在编译时创建函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30970520/