int与void返回类型对栈深度和内存占用无实质影响,差异仅在于字节码指令(return vs ireturn),二者均不支持尾递归优化,栈帧数、大小及stackoverflowerror触发点完全一致。

int 类型本身不直接决定递归栈空间大小,真正影响栈消耗的是每次调用时该参数如何被存储、复用,以及是否伴随其他局部变量和计算逻辑。
每层递归都复制一份 int 参数
在绝大多数语言(如 Java、C/C++)中,int 是值传递。每次递归调用都会把当前 n 的值拷贝进新栈帧的参数槽里。比如 factorial(5) → factorial(4) → … → factorial(1),共 5 层,每层栈帧里都存一个独立的 int n,哪怕值不同、名字相同,内存地址也互不重叠。
- 32 位系统下,每个 int 占 4 字节;64 位系统通常仍按 4 字节对齐处理(除非编译器特别优化)
- 若函数还有其他局部变量(如 a、b、c),它们也会各自分配空间,叠加在参数之上
- 实际栈帧还包含返回地址、调用者现场保存等开销,通常远大于单个 int
引用传参并不节省栈空间
即使写成 const int& n,也不能减少栈深度或每层空间占用。因为 n-1 是右值,编译器必须为它构造临时对象,并在新栈帧中为其分配空间——效果等价于 const int n = n - 1。
- 引用只是别名,不改变生命周期;临时对象仍需存储在栈上(或寄存器溢出时落栈)
- 所有递归层级仍需独立栈帧,无法复用
- 打印地址可能一致,但那是因为编译器做了寄存器优化,不代表物理内存复用
返回类型不影响栈深度
void 还是 int 返回,对栈帧数量和总深度没有实质区别。rt0(int) 和 rt1(int) 在 JVM 中生成的栈帧数、大小、StackOverflowError 触发点完全一致。
- 差异仅在于字节码指令:return vs ireturn,前者不压值,后者要求操作数栈顶有 int
- 两者都不触发尾递归优化(JVM 不支持),每次调用都新建栈帧
- 栈空间消耗主要由调用层数 × 单帧开销决定,而非返回值类型
真正决定栈容量的是递归深度
输入值 n 越大,调用链越长,栈帧越多。例如 n=10000,在默认线程栈 1MB 下极易溢出;而 n=10 则毫无压力。
- 空间复杂度为 O(n),与问题规模线性相关
- 可通过迭代重写消除栈依赖,或改用尾递归友好语言(如 Scala、Kotlin 配合编译器优化)
- 某些场景可手动控制栈大小(如 JVM 的 -Xss 参数),但治标不治本











