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的独立值即可:
- 初始状态: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。
- 执行
- L2调用:x绑定p(当前值6),c值拷贝传入4。
- 执行
c = c-1:L2栈帧内c变为3,不等于0。 - 执行
x = x+1:p从6变为7。 - 递归调用第三层f(记为L3),传入c的当前值3。
- 执行
- L3调用:x绑定p(当前值7),c值拷贝传入3。
- 执行
c = c-1:L3栈帧内c变为2,不等于0。 - 执行
x = x+1:p从7变为8。 - 递归调用第四层f(记为L4),传入c的当前值2。
- 执行
- L4调用:x绑定p(当前值8),c值拷贝传入2。
- 执行
c = c-1:L4栈帧内c变为1,不等于0。 - 执行
x = x+1:p从8变为9。 - 递归调用第五层f(记为L5,基准层),传入c的当前值1。
- 执行
- 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
相关产品推荐
相关产品推荐

