用 std::vector 存储阶乘更安全,因其动态扩容避免越界和内存浪费;需检查负数输入,0! 和 1! 均为 1;20! 以内可用 unsigned long long;手写循环比 std::tgamma 更精确。

用 std::vector 存储阶乘结果更安全
原生数组长度固定,而阶乘增长极快(13! 就超过 int 范围),硬编码数组大小容易越界或浪费内存。用 std::vector<long long></long> 或 std::vector<__int128></__int128>(GCC 扩展)能动态扩容,也方便后续遍历或传参。
常见错误是声明 int arr[100] 后对 i >= 13 的元素赋值,结果溢出为负数或 0,但编译器不报错。
- 输入数组含负数?阶乘无定义,需提前检查并跳过或报错
-
0!和1!都等于1,别漏掉这个边界 - 若输入最大值可能达
20,至少选unsigned long long(支持到20! = 2432902008176640000)
手写阶乘函数比调用库更可控
C++ 标准库没有通用阶乘函数,std::tgamma(n+1) 是浮点近似,对整数大值会丢失精度(如 tgamma(21) 可能返回 2432902008176640000.0 或 2432902008176639800.0),不能用于精确计算。
自己写循环更可靠:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
long long factorial(int n) {
if (n
- 别用递归——
factorial(100)会导致栈溢出 - 循环中不检查溢出,靠类型上限兜底;真要健壮可加
if (res > LLONG_MAX / i)判断 - 输入
n=0时循环不执行,res保持1,逻辑自然成立
批量计算时注意输入范围与性能
如果数组有上百个元素,且每个都要算阶乘,重复计算 5!、6! 等很浪费。可预计算最大 n 值以内的所有阶乘,存入查找表:
std::vector<long long> precompute_factorials(int max_n) {
std::vector<long long> fact(max_n + 1, 1);
for (int i = 2; i <ul>
<li>先遍历输入数组得 <code>max_n = *std::max_element(arr.begin(), arr.end())</code>
</li>
<li>若数组含 <code>0</code> 或负数,<code>max_n</code> 可能为负,需过滤后取最大非负值</li>
<li>查表法 O(1) 每次查询,总复杂度 O(N + max_n),比朴素 O(N × max_n) 快得多</li>
</ul>
<h3>输出或调试时别直接打印 <code>long long</code> 大数</h3>
<p>某些旧环境(如 Windows + MinGW)的 <code>printf</code> 对 <code>long long</code> 支持不稳定,<code>printf("%lld", val)</code> 可能乱码或截断。</p>
<p>更稳妥的方式:</p>
<ul>
<li>用 <code>std::cout —— 流输出对整数类型兼容性好</code>
</li>
<li>若必须用 <code>printf</code>,确认编译器:GCC/Clang 用 <code>"%lld"</code>,MSVC 用 <code>"%I64d"</code>
</li>
<li>调试时打印前加 <code>if (val </code>
</li>
</ul>
<p>真正麻烦的是超 <code>unsigned long long</code> 范围的情况——比如算 <code>100!</code>,这时必须上大数库(如 <code>boost::multiprecision::cpp_int</code>)或自己实现字符串乘法,不是改几个类型就能解决的。</p></long></long>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










