2013-05-06 85 views
1

我做了一个函数,计算一个整数的数字的总和。试图使代码更短,我把评论if语句,看看是否仍然有效,所以我可以删除它,但我得到StackOverflowError,为什么? 这是我的代码:为什么我得到一个StackOverflowError

public static int sumDigits(int n) { 


    //if(n%10==n){ return n;} 

     return n%10+sumDigits(n/10); 

    } 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    System.out.println(sumDigits(12611)); 

} 
+1

这很简单:你得到一个StackOverflowError,因为堆栈溢出。 – Ingo 2013-05-06 13:18:02

+1

考虑一下:“1.呼吸,2.从本清单开始重新开始”。你什么时候会停止呼吸? – 2013-05-06 13:18:24

+3

这是一个经典的例子,如何强制stackoverflowexception,无限递归 – 2013-05-06 13:19:07

回答

4

它从不返回,但只是递归更深入。

您确实有return语句,但在返回之前,需要计算表达式n%10+sumDigits(n/10)的值,该值涉及无限递归。

注意:每次从本身调用函数时,函数的上下文(局部变量)都会添加到堆栈顶部。该堆栈的大小有限。最终你达到这个大小,StackOverflowError是在这种情况下抛出的错误。

2

如果去掉那行,你recursion不具备基本情况下去,这意味着它永远不会返回。

3

这是因为没有停止条款。你将永远调用sumDigits

1

因为您从本身调用sumDigits()并且应该导致您从无限递归返回的代码被注释掉。取消注释行if(n%10==n){ return n;}

1

您的递归没有终止条件。否则,您一次又一次地调用递归函数,最终stack将溢出

0

取消注释停止条件。

3

递归函数可以定义为表示一个操作作为该操作对更接近终点的值的函数。

因此,每一个递归函数需要在某些时候结束条件,否则将复发无限(或者,更准确地说,直到你吹你的堆栈)。

的“数字之和”递归方法的基本定义(为n非负值)为:

def sumOfDigits (n): 
    if n < 10: 
     return n 
    return (n % 10) + sumOfDigits (n/10) # assumes integer division. 

即第一位,结束条件,是非常重要的,你似乎出于某种原因已经评论过你。

2

只要分配给程序的内存中的地址堆栈无法存储任何新地址,就会发生stackover流程错误。

所以当你递归调用sumDigits()时,系统继续保存上次跟踪的LIFO方式。因此系统很容易回到以前的地址,这是递归必须的。

如果无限递归或高于内存约束,您将遇到stackOverflow错误。

1

您注释掉的语句是这个递归函数的基本情况。没有基本的情况下,这个函数将无限循环。


当在主方法制定出例如,你可以获得:
sumDigits(12611)
= 1个+ sumDigits(1261)
= 1 +(1个+ sumDigits(126))
= 1 +(1+(6 + sumDigits(12)))
= 1+(1+(6+(2 + sumDigits(1))))
= 1+ (1 + sumDigits(0)))))//此时注释掉if语句将返回
= 1 +(1 +(6 +(2 +(1 +(0 + sumDigits(0))) )))
= 1 +(1 +(6 +(2 +(1 +(0 +(0 + sumDigits(0)))))))
...

此时程序陷入了无限循环。当n为1时,注释掉的语句会返回,从而避免了这种情况。

相关问题