问题描述
- 递归问题,求n的阶乘?
-
int sum2(n) { int sum=0; if (n<0) printf_s(""error ""); //else if (n == 0 || n == 1) sum = 1; else sum = sum2(n - 1)*n; return sum;}
上图是将注释的话没有写在程序中的结果,不能理解为什么会是这样。。。
解决方案
我给你分析下,你细心看看就明白了。
递归调用就是不断调用自己。然后结合堆栈的原理进行入栈出栈。
比如 f(x)进行递归调用 ,在调用处函数中断。函数环境入栈。
直道有解得时候返回值,中断处得到返回值再进行处理出栈。逐层向上直道最顶层的中断恢复为止。
你可以认为是不断进行任务分解直道有解得时候返回 .(有解指的是函数能执行完毕不再调用其它函数)
所以得到调用序列 f1(x)f2(x)........fn(x) {其中fn=f}
现在我们看你的程序
写阶乘 n! = n*(n-1)!
f(x) = x!
f(n) = n * f(n-1) :函数在f(n-1)中断 fn-1
f(n-1) = (n-1)*f(n-2) : 函数在f(n-2)中断 fn-2
...
...
f(1) = 1 * f(0) : 函数在f(n-2)中断 f0 中断
这个时候就是关键的步骤。我们要设置 函数的解,不然你可以写出 f(-1)f(-2)....
也就是我们要设置函数的出口定义。
既然是出口要写在自身调用的上面,否则先自身调用再出口那么出口就是不可到达。
一旦定义了出口,就是结束函数调用的时点
你程序设计的时点是 :
if (n<0) printf_s(""error
"");
你看程序在此时打印出error之后,会执行什么啊? 应该是 return sum巴
sum是多少阿? 由于你在函数首句定义了sum=0所以最后一次返回的是0
这样 导致没层中断的返回值都是0
所以结果就是0了
按照上面的分析你可一写出
if(n==1) return 1 retturn sum2(n - 1)*n
解决方案二:
试试下面的:
int sum = 1;
int sum2(int n)
{
if(n > 1)
{
sum = n * sum2(n - 1);
}
return sum;
}
另外: 不要加n < 0时打印error的语句,因为n会一直递减,最终都会小于0,error就打印出来
解决方案三:
01./*
02.*Copyright (c) 2014烟台大学计算机学院
03.*All rights reserved.
04.*文件名称: test.cpp
05.*作 者:李晓凡
06.*完成日期:2014年11月10日
07.*版本号:v1.0 ......
答案就在这里:用递归求n的阶乘
解决方案四:
按照你的程序自己一步步计算一下sum2(1)的每一步结果,应该能清楚。
解决方案五:
sum2(0)返回0,0乘任何数都是0。所以你注释掉的那句很关键。
解决方案六:
语法有错,if后面打印error之后加了“;”正常的为 if(){} else {}
解决方案七:
int sun2(int n)
{
if(n > 1)
{
return n*sum2(n-1);
}
else
{
return 1;
}
}
解决方案八:
int sun2(int n)
{
if(n > 1)
{
return n*sum2(n-1);
}
else
{
return 1;
}
}