用for循环计算阶乘最稳妥:初始化unsigned long long result=1,循环i从1到n累乘,逻辑清晰、不易出错,适用于n≤20。

用 for 循环算阶乘最稳妥
直接用 for 循环从 1 乘到 n,是 C++ 里计算阶乘最直观、最不容易出错的方式。适合 n ≤ 20(unsigned long long 范围内),超出会溢出但至少逻辑清晰。
- 初始化一个
result = 1,类型选unsigned long long(避免负数干扰,且比int能多撑几阶) for (int i = 1; i ,注意边界是 <code>,不是 <code>- 每轮做
result *= i,别写成result = result * i + 1这类常见笔误 - n 为 0 时循环不执行,
result保持 1,正好符合 0! = 1 的定义
while 循环也能用,但得手动管计数器
如果偏好 while,它和 for 等价,但变量作用域和递增位置更易出错。
- 必须显式声明并初始化计数器,比如
int i = 1和unsigned long long result = 1 - 循环条件写成
i ,循环体末尾必须有 <code>++i(漏掉就死循环) - 和
for相比,while把三要素(初始化、条件、更新)拆开了,调试时容易漏看某一部分 - 示例片段:
int i = 1;<br>unsigned long long result = 1;<br>while (i <= n) {<br> result *= i;<br> ++i;<br>}
别用递归算阶乘——除非你明确要练手或处理极小 n
递归写法看着简洁,但实际在 C++ 中几乎没优势,还容易栽跟头。
- 函数调用开销明显,n 大一点(比如 > 1000)就可能栈溢出,而循环完全没这问题
- 编译器不一定对
factorial(n-1)做尾递归优化(C++ 标准不保证),所以不能指望它自动转成循环 - 如果真要用,务必加边界检查:
if (n ,否则负数输入会无限递归 - 返回类型仍得是
unsigned long long,递归函数声明写成unsigned long long factorial(int n)
溢出检测不能靠感觉,得动手加判断
C++ 不自动报阶乘溢出,result * i 溢出后值直接回绕(比如变 0 或极大正数),结果完全不可信。
立即学习“C++免费学习笔记(深入)”;
- 简单办法:乘之前检查
result > ULLONG_MAX / i(需#include <climits></climits>),成立说明即将溢出 - 更实用的是限制输入范围——比如只接受
n ,并在运行时用 <code>if (n > 20) { /* 报错或返回错误码 */ } - 别依赖
std::numeric_limits<unsigned long>::max()</unsigned>做实时除法判断,整数除法截断可能误判;用预计算的阈值更稳(20! = 2432902008176640000) - 一旦溢出发生,后续所有计算都失效,没法“恢复”,只能提前拦住
实际写的时候,95% 的情况用第一个 for 循环方案就够了。真正麻烦的从来不是怎么写循环,而是忘了溢出这件事,或者把 0! 当成特例单独 if 判断——其实根本不用,初始值设对就行。


















