递归调用函数时出现分段错误
我在大学学习C,而我是编程新手。我的任务是创建一个函数,它应该为我的输入计算一个弧线。递归调用函数时出现分段错误
我试图用xcode进行调试。一切正常,直到返回arcsin(新);叫做。那么它的一个分段错误:11。我不知道为什么,但浮点的断点arcsin(floatvalue){...在运行第二个循环时告诉我浮动值和浮点值是NAN。
float arcsin(float value){
float old = value;
float new = value + (0.5 * ((value * value * value)/3));
float accurate = 0.00001;
if ((new - old) < accurate){
return new;
}
else{
return arcsin(new);
}
}
int function_arcsin(int sigdig, float value){
value = arcsin(value);
printf("%.10e\n",value);
return 0;
}
当调用堆栈变得太大 - 即递归级别太多时,会发生seg错误。
就你而言,这意味着条件(new - old) < accurate
将始终评估为假 - 也许并不总是,但足够的时间膨胀调用堆栈。
测试你的代码我发现new
(可能不是一个好的变量名称选择)一直在增长,直到超过float的极限。你的算法可能是错误的。
'new'这个名字也让我想起了一秒钟,因为它是C++中的一个关键字,但是这真的算作C中一个不好的选择吗? (我现在不熟悉C风格的规则)。 – Steve314
@ Steve314你永远不知道什么时候你想要将代码移植或包含到C++中,现在不妨选择好,而不是稍后重构,对吗? –
@ Steve314这种无意义的变量名称作为'new'或'old'应该在任何语言中都被认为是不好的选择 –
我很确定分段错误是由太深的递归引起的。虽然许多编译器可以将很多递归代码优化为迭代代码,但有些编译器却不行,而且这很常见。调试选项来禁用它。
转换为迭代形式将停止段错误 - 但是,除非我错过我的猜测,否则请给出无限循环。我不希望工作递归解决方案成为一个问题在这里,除非你正在测试超出范围的近似值收敛 - 在这种情况下,我的第一个猜测是输入范围-pi到+ pi应该可以用于任何可用的近似弧线。
我并不熟悉arcsin的迭代逼近,而我的google-fu还没有找到答案,但我怀疑你在float new = ...
行中的计算错了。
我发现这个链接...
http://mathforum.org/library/drmath/view/54319.html
这不是有益的 - 你的代码是不是暗示描述这两种方法的。
我测试你的程序,看到永远不会结束循环:
((new - old) < accurate) // never is true
,如果你用数字> 0尝试,在10次迭代达到楠。用数字< 0,继续数千次,并导致太深的递归。
新是一个保留关键字。叫它像float newval – spicavigo
@spicavigo:这是C,而不是C++,所以没关系。 – bitmask
@spicavigo不是普通的C. –