使用类似位图的宏在编译时创建函数

标签 c macros

我有一个 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/

相关文章:

c - 正确扫描除 '+' 和 '-' 之外的字符

c - C 编译器如何处理不同类型的声明?

c - 可视化二叉树的递归

macros - 非递归符号-macrolet

c - feof(in) != EOF 不会使 while 循环在文件末尾停止?

C size_t 和 ssize_t 负值

c++ - 预处理器宏 : how to insert arguments?

ios - Objective-C: "format string is not a string literal (potentially insecure)"宏警告

c - 如何正确使用STDERR_FILENO?

将一行函数转换为c中的宏