Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions Recursion/factorial.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
#include <assert.h>
#include <stdio.h>
#include <stdbool.h>

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;
}