diff --git a/Recursion/factorial.c b/Recursion/factorial.c index d4dc5e0..0e1cf23 100644 --- a/Recursion/factorial.c +++ b/Recursion/factorial.c @@ -1,22 +1,45 @@ #include +#include +#include -long long factorial(int n) -{ - if (n < 2) { - return n; +// 迭代实现,避免递归栈开销 +long long factorial(int n) { + // 处理非法输入(负数) + if (n < 0) { + fprintf(stderr, "错误:负数没有阶乘\n"); + return -1; // 用特殊值表示错误 + } + // 0! 和 1! 直接返回 1(数学定义:0! = 1) + if (n == 0 || n == 1) { + return 1; } - return n * factorial(n - 1); + long long result = 1; + for (int i = 2; i <= n; ++i) { + // 溢出检测:如果乘以 i 后超过 long long 最大值,则溢出 + if (result > LLONG_MAX / i) { + fprintf(stderr, "错误:n = %d 时阶乘溢出(超过 long long 范围)\n", n); + return -1; // 用特殊值表示错误 + } + result *= i; + } + return result; } -int main() -{ +int main() { + // 测试用例(包含 0! 的情况,修正原代码逻辑) + assert(1 == factorial(0)); // 0! = 1(数学定义,原代码返回 0 是错误的) + assert(1 == factorial(1)); assert(2 == factorial(2)); assert(6 == factorial(3)); assert(120 == factorial(5)); assert(3628800 == factorial(10)); - assert(1307674368000 == factorial(15)); - assert(2432902008176640000 == factorial(20)); + assert(1307674368000LL == factorial(15)); + assert(2432902008176640000LL == factorial(20)); + + // 测试溢出和非法输入(不会触发 assert 失败,仅打印错误) + factorial(21); // 溢出 + factorial(-5); // 负数 return 0; }