GESP 五级 · GESP 202312 C++ 五级 第 3 题

选择题 · 答案 D · 考点:函数

← 整套速查表 GESP 五级 全部真题

题目

阅读下面的 C++ 代码,执行后其输出是( )。

int stepCount = 0;
int fracA(int N)
{
    stepCount += 1;
    cout << stepCount << "->";
    int rtn = 1;
    for (int i = 1; i <= N; i++)
        rtn *= i;
    return rtn;
}
int fracB(int N)
{
    stepCount += 1;
    cout << stepCount << "->";
    if (N == 1)
        return 1;
    return N * fracB(N - 1);
}
int main()
{
    cout << fracA(5);
    cout << "<==>";
    cout << fracB(5);
    return 0;
}
答案:D

考点

函数

解题思维

全局变量stepCount是贯穿整个程序的生命线,先理清fracA和fracB各自会触发多少次stepCount自增,再按调用顺序把打印结果串起来就能锁定答案。

常见错误

最大的坑在于忽视stepCount的全局属性,误以为每个函数内部计数器是独立的,从而在fracB开头错误地输出1->;其次是递归思维定势,看到分形或阶乘就下意识想“循环算一次就够了”,忽略了函数调用栈中每层递归入口都会执行一次stepCount++和cout,导致漏掉中间那些2->3->4->5->的打印;还有人会纠结返回值计算,其实题目只问输出,只要数清打印次数和顺序即可。

详细解析(节选)

这道题表面看是阶乘计算,实则考的是全局变量的跨函数追踪与递归调用栈的执行流程。命题人把stepCount设计成全局变量,就是要考察考生能否跳出单个函数的视角,看到整个程序运行过程中计数器的连续累加。很多人一看到fracB(5)就会想“这是递归求阶乘,肯定是一口气算完”,从而忽略每层递归入口那一次执行,导致在选项A或B里犯错。正确的思路是:先模拟main函数里fracA(5)的执行,stepCount从0开始,进入fracA立即+1变为1并打印“1->”,循环1到5乘出120返回;此时stepCount保持为1。接着main打印“<==->”,然后调用fracB(5)。进入fracB时stepCount先+1变为2,打印“2->”,此时函数还没开始递归,只是记录了这次调用。然后判断N==1不成立,进入return 5*fracB(4)。这里要注意,递归调用fracB(4)会再次触发fracB的入口,stepCount+1变为3,打印“3->”;再递归fracB(3)时stepCount+1变为4,打印“4->”;继续下去,fracB(2)使stepCount变为5,打印“5->”;最后fracB(1)使stepCount变为6,打印“6->”,此时N==1成立,直接return 1,不再继续递归。随着递归逐层返回,每一步乘法运算在C++里都是立即执行的,但题目只要求输出,所以最终fracB(5)返回120,main打印“120”。把两部分的输出连起来就是“1->120<==>2->3->4->5->6->120”,对应选项D。易错点除了全局变量意识外,还有对递归执行顺序的误解:有人以为递归是“先全部调用完再返回”,其实每层调用都会在入口处执行stepCount++和cout,所以打印顺序是严格按调用栈入栈顺序排列的。若把stepCount改成局部变量,每个函数内部计数器独立,fracB开头就会输出1->,那就变成选项B了;若把fracB改成循环实现,stepCount只会在循环外自增一次,输出也会完全不同。这道题在GESP五级属于高频考点,历年真题中涉及递归与全局变量联合追踪的题目占比很高,命题人特别喜欢在递归入口处埋下全局变量来制造陷阱,考生必须养成“看到递归先标出入口执行点”的习惯。基于历年考频数据,这类题型在2023-2026年间持续出现,且难度逐年略有提升,未来仍可能以类似形式考察,提醒大家在练习时要刻意训练全局变量与递归的交叉分析能力。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断