You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++递归题:p初始为5时区分传参类型求f(p,p)返回值

问题重述

已知C++函数定义如下,调用前变量p初始值为5,求f(p,p)的返回值。函数参数传递规则:第一个形参为引用传递,第二个形参为值传递。

int f (int &x, int c)
{
    c = c - 1; 
    if (c == 0) return 1;
    x = x + 1;
    return f(x,c) * x;
}
核心机制前置说明
  • 引用传递(形参x):所有递归层级中的x都绑定到最外层的变量p,任何对x的修改都会直接修改p的值,所有层级读取x时拿到的都是p的最新值,不存在独立拷贝。
  • 值传递(形参c):每次函数调用时,c是传入实参的独立副本,函数内部对c的修改仅在当前调用栈帧内生效,不会传回外层调用,也不会影响其他递归层级的c值。
  • 表达式求值顺序:return f(x,c) * x;语句会先完整执行递归调用f(x,c)拿到返回值,再读取当前x的值完成乘法运算——递归执行过程中对x的所有修改,都会在乘法执行时体现。
逐轮递归执行推导

从最外层调用开始逐层跟踪栈帧状态,其中x始终对应外层变量p,跟踪p的当前值、每一层c的独立值即可:

  1. 初始状态:p=5,调用第一层f(记为L1),x绑定p,c值拷贝传入p的初始值5。
    • 执行c = c-1:L1栈帧内c变为4,不等于0,不触发基准返回。
    • 执行x = x+1:p从5变为6。
    • 准备执行return f(x,c)*x,先递归调用第二层f(记为L2),传入c的当前值4。
  2. L2调用:x绑定p(当前值6),c值拷贝传入4。
    • 执行c = c-1:L2栈帧内c变为3,不等于0。
    • 执行x = x+1:p从6变为7。
    • 递归调用第三层f(记为L3),传入c的当前值3。
  3. L3调用:x绑定p(当前值7),c值拷贝传入3。
    • 执行c = c-1:L3栈帧内c变为2,不等于0。
    • 执行x = x+1:p从7变为8。
    • 递归调用第四层f(记为L4),传入c的当前值2。
  4. L4调用:x绑定p(当前值8),c值拷贝传入2。
    • 执行c = c-1:L4栈帧内c变为1,不等于0。
    • 执行x = x+1:p从8变为9。
    • 递归调用第五层f(记为L5,基准层),传入c的当前值1。
  5. L5调用(基准情况):x绑定p(当前值9),c值拷贝传入1。
    • 执行c = c-1:L5栈帧内c变为0,触发基准返回,直接return 1,不会执行后续的x自增逻辑,p保持9不变。

递归触达基准层后开始逐层返回计算乘积:

  • L5返回值1回到L4的调用点,此时p=9,L4计算1 * 9 = 9,将9返回给L3。
  • L4返回值9回到L3的调用点,此时p仍然是9(后续无任何修改x的逻辑),L3计算9 *9 =81,将81返回给L2。
  • L3返回值81回到L2的调用点,p=9,L2计算81 *9=729,将729返回给L1。
  • L2返回值729回到L1的调用点,p=9,L1计算729 *9=6561,得到最终返回值。
常见计算误区
  • 误区1:误以为第二个参数c会随p变化。实际上c是值传递,第一次调用时就完成了值拷贝,后续p的修改和所有层级的c完全无关。
  • 误区2:误以为乘法取的是递归调用前的x值。比如错误计算为678*9=3024,本质是忽略了递归调用会先完整执行、把x修改到最终值9之后才会做乘法,所有非基准层的乘法操作乘的都是最终的x=9。
  • 误区3:误以为基准层L5会执行x自增。实际上L5触发c==0的判断后直接返回,不会执行x = x+1,因此x最终值是9而非10。
最终结果

f(p,p)的返回值为 6561。

内容的提问来源于stack exchange,提问作者Lakshmi Sathyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:54:23