Java递归调用中num-1与num--传参的计算差异疑问(非栈溢出现象解释)
Java递归调用中num-1与num--传参的计算差异疑问(非栈溢出现象解释)
先回顾下你给出的代码片段,方便对照理解:
public static void main(String[] args) { doubt1(5); } // 前缀自减:正常执行 static void doubt(int num) { if(num==0) return; System.out.println(num); doubt(--num); } // 后缀自减:栈溢出 static void doubt1(int num) { if(num==0) return; System.out.println(num); doubt1(num--); }
嘿,我来给你把这个点讲透——核心差异完全在于这两个表达式的求值逻辑和副作用触发顺序,咱们完全聚焦你问的「为什么num-1会生效而num--不会」,不重复栈溢出的原因:
首先先明确两个表达式在传参时的执行步骤:
1. 关于num-1的传参逻辑
当你把递归调用改成doubt1(num-1)时:
- Java会先执行减法运算:用当前方法中
num的当前值,计算出num-1的结果(比如当前num是5,就算出4); - 然后把这个计算出来的全新数值传递给下一层递归方法;
- 注意:这里原方法中的
num变量本身完全不会被修改,只是用它的值做了一次临时计算。
所以每一层递归拿到的参数都是比上一层小1的数,直到参数变成0触发终止条件,递归正常结束。
2. 关于后缀num--的传参逻辑
后缀自减运算符num--的规则是**「先返回原始值,再执行减1」**,放到递归调用里看:
- 当你调用
doubt1(num--)时,Java会先把当前方法中num的原始值(比如第一次调用时是5)直接传递给下一层递归; - 只有在完成参数传递、进入下一层递归之前,才会把当前方法里的
num减1; - 但关键问题是:下一层递归拿到的参数还是原始的5啊!每一层都传进去相同的数值,永远触发不了
num==0的终止条件,递归就会无限进行下去。
额外对比:前缀--num和num-1的区别
其实前缀自减--num的逻辑和num-1类似:都是先计算出减1后的数值,再传递给递归方法。但不同的是,--num会修改原方法中的num变量,而num-1只是临时计算,不会改变原变量的值——不过这一点在你的递归场景里不影响终止条件的触发,因为两者都能传递正确的递减数值。
备注:内容来源于stack exchange,提问作者Tholkappiar
相关产品推荐
相关产品推荐

