你能在 C 中有一个阶乘宏吗?

kin*_*986 0 c macros

我正在寻找阶乘宏的示例。我没有找到任何有效的东西。有没有一个特定的原因?这是因为 C 的实现吗?

所以,为了让问题更清楚.......我一直无法在 C 的编程语言中找到阶乘宏。我知道你不能在宏中使用递归,但是有一种方法可以有一个迭代阶乘函数。为什么在 C 中不可能有阶乘宏?

作为参考,这里是我发现的阶乘函数迭代实现的示例:

int factorial(int N) {
    int product = 1;
    for (int j = 1; j <= N; j++)
        product *= j;
    return product;
}
Run Code Online (Sandbox Code Playgroud)

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

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

chq*_*lie 5

我想不出一种在一般情况下使它成为宏的方法,因为int定义阶乘函数的值很少:N > 12如果int有 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])
Run Code Online (Sandbox Code Playgroud)

或者:

#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)
Run Code Online (Sandbox Code Playgroud)

请注意,这两者都会评估n多次。

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

使用Matt Goldberg 的在线编译器和 clang 3.9 -O2的简短示例非常有启发性:

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

test():                               # @test()
        mov     eax, 479001600
        ret
Run Code Online (Sandbox Code Playgroud)

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