你能用C中的因子宏吗?

时间:2016-11-22 04:07:28

标签: c macros

我正在寻找一个阶乘宏的例子。我找不到任何有用的东西。是不是有一个特定的原因?这是因为C&C的实施?

所以,试图让问题更清楚......我无法在C的编程语言中找到一个因子宏。我明白你不能在宏中有递归,但是有一种具有迭代阶乘函数的方法。为什么在C中不可能有一个阶乘宏?

这里的参考是我发现的阶乘函数的迭代实现的一个例子:

int factorial(int N) {
    int product = 1;
    for (int j = 1; j <= N; j++)
        product *= j;
    return product;
}

这是一个进一步了解C语言及其使用宏的问题

请解释为什么这个问题被投票否决了。这是一个更好地理解C的问题。

1 个答案:

答案 0 :(得分:2)

我无法想到在一般情况下将其设为宏的方法,因为定义了阶乘函数的int值非常少:如果{N > 12,它会调用int的未定义行为{1}}有32位。

有很多方法可以利用这个:

static int const factorials[13] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 
                                    362880, 3628800, 39916800, 479001600 };
#define FACT(n)  ((n) < 0 ? 1 : (n) > 12 ? INT_MAX : factorials[n])

可替换地:

#define FACT(n) ((n) <= 1 ? 1 : \
                 (n) == 2 ? 2 : \
                 (n) == 3 ? 6 : \
                 (n) == 4 ? 24 : \
                 (n) == 5 ? 120 : \
                 (n) == 6 ? 720 : \
                 (n) == 7 ? 5040 : \
                 (n) == 8 ? 40320 : \
                 (n) == 9 ? 362880 : \
                 (n) == 10 ? 3628800 : \
                 (n) == 11 ? 39916800 : \
                 (n) == 12 ? 479001600 : INT_MAX)

请注意,这两个评估n多次。

内联函数是一种更好的方法。您的factorial()可能会编译为常量,以便在现代优化编译器上进行常量参数:

使用Matt Goldberg's online compiler和clang 3.9 -O2的简短示例非常有用:

factorial函数编译成一条深不可测的235行英特尔SIMD代码,而int test(void) { return factorial(12); }只生成2条指令:

test():                               # @test()
        mov     eax, 479001600
        ret

即使使用-Os优化大小也会产生49行汇编代码,因为-O1在10行时要小得多。