C#函数无限递归 递归c# 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 while(true){}跟着效果应该差不多 完全不一样while循环只不过是吃cpu无限递归会吃内存因为每递归一次,之前的也不会释放,依然保留着,好等你递归完了再一层一层的退出出来 List<double> l=new List<double>();while(true){l.add(0.0f);}你要是说跟这个差不多还有点靠谱只往里加,永远不删除,总有内存溢出的时候 func<int,int> func=null;func=c=>fun(c-1)+c ;//没有退出条件int res=func(100000);运行这个你试试看是什么效果 理论上每次调用函数都会将其地址加载到堆栈上,所以都有次数限制拿个简单例子来说:static int Test(int i) { if (i < -500000) { return 1; } return Test(i - 1) + i; }Test(i - 1) + i因为有+i的运算,需要把上一次递归的结果暂存到一个临时变量,加载到栈上,随着次数的增加,会占用越来越多的堆栈,而线程的堆栈是有限的(默认1M)不过编译器可以优化尾递归形式(函数直接返回自身的调用),右侧改为return Test(i - 1) ,这样就不需要临时变量(func的地址是固定的),编译器就可以将其优化成循环,跳转到原地址,传入新的参数在工程属性中勾选“允许优化代码”后(或者Release生成),就不会溢出了,不勾选就溢出LS的代码由于没有退出条件,优化后将造成死循环 一般来说结果就是StackOverflowException导致程序结束。不过具体行为不仅和程序有关,还和编译器还有jit有关。调用有一种尾调用,它可以进行优化,调用时其实当前方法已经结束,就可以先对栈进行处理再调用。这种对递归来说就是尾递归,不需要栈不停增长。IL有tail指令来通知jit尾递归,但是C#的编译器不会产生这个指令(F#的编译器会),而是jit自动根据情况优化,只有release方式编译后,在64位jit的执行才支持。clr4对尾调用又进行过优化。比如以下最简单的递归,如果是Release模式64位运行,就会无限循环,类似于while(true),而其它方式运行都会stack overflowpublic static void R(){ R();}但是自己也无法确定jit会不会进行尾调用优化,而且StackOverflowException是无法catch的,会直接导致程序结束。所以数据量大时要自己根据情况控制好递归深度,避免栈溢出。或者转化成不使用递归的算法。 哈,我比较好奇楼主为什么会有这么个问题怎么想“无限”递归都是件耗资源耗CPU的事,程序跑“累了”就会理所当然地崩掉,但是不会影响到系统。 堆栈溢出。你使用的局部变量越多,递归的层数越少。递归的层数没有限制,限制是堆栈的大小,默认CLR使用4MB的堆栈。 无限递归会导致栈溢出,系统随即抛出 OverflowException C#多窗体窗体层次问题 请高手解释一下关于precise和beforefieldinit的三个例子 求用C#写的OutLook风格的界面 问一个关于excel的问题高手赐教! 请教:静态页面和动态页面的流量问题。 100分求助C#中MDI程序怎么获得当前激活的子窗体 在线等 关于static对这个理解比较深的人进来看看 哪里有c#版本的asp.net电子书下载? 我被激怒了!!!!!斑竹都是干什么的????????????????? WebControls.TreeView问题 Aforge同時显示多个摄像头的问题(急) c# VS2010 double 和 Double 有什么区别。
{
}
跟着效果应该差不多
while循环只不过是吃cpu
无限递归会吃内存
因为每递归一次,之前的也不会释放,依然保留着,好等你递归完了再一层一层的退出出来
while(true)
{
l.add(0.0f);
}
你要是说跟这个差不多还有点靠谱
只往里加,永远不删除,总有内存溢出的时候
func=c=>fun(c-1)+c ;//没有退出条件
int res=func(100000);运行这个你试试看是什么效果
拿个简单例子来说:static int Test(int i)
{
if (i < -500000)
{
return 1;
}
return Test(i - 1) + i;
}Test(i - 1) + i因为有+i的运算,需要把上一次递归的结果暂存到一个临时变量,加载到栈上,随着次数的增加,会占用越来越多的堆栈,而线程的堆栈是有限的(默认1M)不过编译器可以优化尾递归形式(函数直接返回自身的调用),右侧改为return Test(i - 1) ,这样就不需要临时变量(func的地址是固定的),编译器就可以将其优化成循环,跳转到原地址,传入新的参数
在工程属性中勾选“允许优化代码”后(或者Release生成),就不会溢出了,不勾选就溢出LS的代码由于没有退出条件,优化后将造成死循环
{
R();
}但是自己也无法确定jit会不会进行尾调用优化,而且StackOverflowException是无法catch的,会直接导致程序结束。所以数据量大时要自己根据情况控制好递归深度,避免栈溢出。或者转化成不使用递归的算法。
你使用的局部变量越多,递归的层数越少。
递归的层数没有限制,限制是堆栈的大小,默认CLR使用4MB的堆栈。