【发布时间】:2015-09-20 06:48:04
【问题描述】:
我正在使用尾递归编写阶乘,我在这里有一个问题。我原来的功能是这样的
代码 sn-p A
#include <stdio.h>
int main(void)
{
int n = 0;
printf("Enter number to find factorial of : ");
scanf("%d",&n);
printf("fact == %d\n",fun(n,1));
return 0;
}
int fun(int n, int sofar)
{
int ret = 0;
if(n == 0)
return sofar;
ret = fun(n-1,sofar*n);
return ret;
}
但是,即使我不使用 return,它仍然有效。这并不完全合理,因为我只在基本情况下返回值。假设如果 n==5,则在基本情况下将返回 120。但是无法预测从第 4 次调用返回到第 3 次调用的返回值,因为我们没有像代码 sn-p A 中那样明确指定任何返回值。
代码 sn-p B
int fun(int n, int sofar)
{
int ret = 0;
if(n == 0)
return sofar;
ret = fun(n-1,sofar*n);
}
我认为上述工作是因为某种编译器优化?因为如果我在 Code sn -p B 中添加一个 printf 语句,它就不再起作用了。
代码 sn-p C
int fun(int n, int sofar)
{
int ret = 0;
if(n == 0)
return sofar;
ret = fun(n-1,sofar*n);
printf("now it should not work\n");
}
可能是 printf 导致从堆栈中删除某些内容?请帮助我理解这一点。
【问题讨论】:
-
你想了解UB吗?不要打扰。
-
@deviantfan 考虑到 UB 在生产代码中非常常见(我听说估计超过 90% 的程序都包含 UB),我想说人们应该费心去理解 UB,了解它以知道如何避免和修复它是非常关键的。
-
@Art 了解问题所在/如何解决问题并了解为什么在 UB 情况下会发生一些奇怪的事情是一个很大的不同......
-
发布的代码在编译时会引发严重警告,即缺少“fun()”的原型。建议将该原型放在 main() 函数之前。
标签: c++ c recursion tail-recursion factorial