有关下面 C++ 代码说法错误的是( )。
// sumA()和sumB()用于求从1到N之和
#include <iostream>
using namespace std;
int sumA(int n) {
int sum = 0;
for (int i = 1; i < n + 1; i++)
sum += i;
return sum;
}
int sumB(int n) {
if (n == 1)
return 1;
else
return n + sumB(n - 1);
}
int main() {
int n = 0;
cin >> n;
cout << sumA(n) << " " << sumB(n) << endl;
return 0;
}这题表面考循环与递归的区别,实则挖的是递归栈溢出陷阱。拿到题先别急着算结果,要盯着 sumB 的递归层数:输入 n 时,sumB 会调用 n 次,每次压栈。选项 C 的 100000 层递归远超普通系统栈默认大小(通常 1MB-8MB),必然崩溃,这就是命题人设的坑。
学生最容易犯的错误是只关注时间复杂度,认为 O(n) 的递归和循环效率差不多,或者误以为现代计算机内存无限大,能跑 100000 层递归。其实递归的瓶颈在于栈空间(Stack Space),每层调用都要占栈帧,100000 层递归需要的栈深度远超默认限制,导致程序崩溃。另外,部分学生可能混淆 sumA 和 sumB 的效率,认为两者都是 O(n),忽略了递归的额外栈开销。
本题出自 GESP 五级,核心考查递归函数的执行机制与栈空间限制。命题人通过对比循环(sumA)与递归(sumB)两种实现求和的方式,特意设置了一个看似“无害”的输入值(100000),实则测试考生对递归调用栈深度(Stack Depth)与系统默认栈大小(Default Stack Size)之间关系的物理认知。绝大多数考生只知“递归能算”,却不知“递归算太大数会爆栈”,这正是本题的命题视角。