J2SE论坛网»J2SE技术»帮忙分析下一个很小的程序!

帮忙分析下一个很小的程序!

问?:
你知道下面这个程序运行的结果是多少吗?
class Fact{
private int sun;
private int n;
int fan(int i){
n = i;
System.out.println(n);
if(n == 1) return 1;
sun = fan(n -1)*n;
return sun;
}
}

class Recursions{
public static void main(String args[]){
Fact ob1 = new Fact();
System.out.println("The ob1 de jiecheng is: " + ob1.fan(3));

}
}

结果是1而不是6,为什么?
大牛们来来讲讲是为什么啊。
答!: 1:
sun = fan(n -1)*n;
你的这一句是一个递归调用!怎么会得到6呢?
答!: 2:
int fan(int i){
if(i == 1) return 1;
return fan(i -1)*i;
}
这样吧
答!: 3:
要想等于6那就的这样:
sun = n*fan(n -1);
因为你那样n最后读取的是1
这样先读取n就ok了
答!: 4:
re楼上的:
我当然知道这是递归调用
如果“private int n”换成“int n”,结果就是6,
结果为1怎么解释呢?
答!: 5:
要么你这样:
class Fact{
private int sun;

int fan(int i){
int n;
n = i;
System.out.println(n);
if(n == 1) return 1;
sun = fan(n -1)*n;
return sun;
}
}

class Recursions{
public static void main(String args[]){
Fact ob1 = new Fact();
System.out.println("The ob1 de jiecheng is: " + ob1.fan(3));

}
}
答!: 6:
明白乐,原来你的n是全局变量,你n-1最后n变成乐1,你希望的fan(n -1)*n,当你=2的时候去取f(2-1),可你把n-1传给i,i再传给n,导致n最后只是1乐,成乐f(1)*1*1乐
答!: 7:
class Fact{
private int sun;
//private int n;
int fan(int i){
int n;
n = i;
System.out.println(n);
if(n == 1) return 1;
sun = fan(n -1)*n;
return sun;
}
}

这样写
答!: 8:
我想知道的并不是程序怎样写的问题,
而是对于运行结果为1的一个合理解释,
希望大家继续指点。
答!: 9:
int fan(int i){
n = i;
System.out.println(n);
if(n == 1) return 1;
//递归到这里的时候就直接返回了1,所以结果就是1,无论i是什么值都只能返回1

sun = fan(n -1)*n;
return sun;
}
答!: 10:
还有一点我不明白

yysky2005上面说的:

“re楼上的:
我当然知道这是递归调用
如果“private int n”换成“int n”,结果就是6,
结果为1怎么解释呢?”

为什么“private int n”换成“int n”,结果就是6???
yysky2005能解释一下吗?
答!: 11:
1.得到的结果是
if(n == 1) return 1;
返回的;

2.递归调用既 每次都要重新进入方法体再次执行;

3.运行过程:
fan(3-1)*3-->fan(3-1-1)*2*3-->此时调用fan(1),则if(n == 1) return 1直接返回 1,
下面的sun=fan(n-1)*n就再也执行不到;

4.无论你输入多大的值结果都将是1。


答!: 12:
你有一句:n = i;
所以最后f() * n时,n总是 1。
改为: n * f();
答!: 13:
过程为:
fun(3) ->
n -> 3;
(1): fan(3 - 1) * n;(实际上为fun(2)*n)
fun(2) ->
n -> 2;
(2): fun(2 - 1) * n;(实际上为fun(1)*n); <注意这边已经修改了private int n=2>
fun(1) ->
返回1 (这边private int n = 1)

递归返回(2) 1*1 = 1;
递归返回(1) 1*1 = 1;
所以结果为1;
答!: 14:
mark!!
答!: 15:
过程为:
fun(3) ->
n -> 3;
(1): fan(3 - 1) * n;(实际上为fun(2)*n)
……

如果是这样那还可以理解
那为什么不是fan(3 - 1) * 3呢?n不是已经赋值为3了吗?
答!: 16:
递归是通过栈来处理的,也就是最先算得是
fan(1)
由于你的n是全局变量所以在算fan(2)的时候你的n已经是1了。
答!: 17:
那个把sun定为全局变量的,真垃圾
答!: 18:
你跟中下不就行了
到sun = fan(n - 1) * n;时
递归调用fan(n-1)也就是fan(3-1)
n=2;n依然不等于1
所以继续递归调用
fan(n-1)参数为n-1 也就是2-1
n=i;
n==1;
返回1
1*n==1*1;
结果1
答!: 19:
原来楼主问的是过程

综合 楼上大家理解,我是这样理解的:
n=i,也就是说i的地址指向n,n有时成员变量,在Fact类地址是不变的吧
开始运算了,
n=3时,sun = fan(3 -1)*n;注意,因为要递归,所以这一步没有计算*n的结果,
先把fan(3-1)的值算出来
n=2时,sun = fan(2 -1)*n;同样,先算fan(3 -1)等于2的值
n=1时,fan(1)就等于1了,回过头来在算*m

因为n时成员变量,n=1,一路算回去的n都是1,乘来乘去都是1,结果就是1了
并不像有些人认为那样,直接n=1,返回1就出去了,还是有计算的过程的

如果你把int n,拿到方法里,n 就是局部变量了,Fan()方法访问一次,就重新初始化,赋值
所有int n后,每次的*n,n都是新地址的新的n
比如:n=2时,fan()方法第2次被访问,n第二次被赋值,n=2,回来*n,的时候,应该就乘以这次n从i得到2的这个值

说白了,int n在方法里,n就是当i用,指向的同一个地址

int fan(int i){
if(i == 1) return 1;
return fan(i -1)*i;
}

所以,如此!
个人理解,对JVM的机制只是做一些猜测而已,最好是跟踪运算过程,看看字节码流最好了!

小弟初学java没多久,这里侃侃,献丑了!

答!: 20:
真是扯淡,我用eclipse编译运行,结果int n ; 和private int n ;输出的都是1;没有时6 ;
答!: 21:
因为方法执行时,是栈中进行的。
执行完一次,所得到的值就被释放了,
应把全局变量定义为局部变量!
class Fact{
int fan(int i){
int n;
n = i;
System.out.println(n);
int sun;
if(n == 1) return 1;
sun = fan(n -1)*n;
return sun;
}
}

class Recursions{
public static void main(String args[]){
Fact ob1 = new Fact();
System.out.println("The ob1 de jiecheng is: " + ob1.fan(3));

}
}
答!: 22:
插播一条广告,小店新开张,优惠出售各种手工艺品,欢迎大家选购,是各位帅哥送女朋友、老婆、情人(OR各位美女送男朋友、老公、情人)的不二选择
http://shop33881320.taobao.com/
答!: 23:
sun = fan(n -1)*n;
应该改为
sun = n*fan(n-1);

结果是6.

相关JAVA教程:
按鼠标左键,光标移动的event.keyCode=???
有做过类似Editplus编辑器的吗?文本编辑,左边显示1、2、3..所在的行数,是怎么实现的?
窗口间如何传递键盘消息?
如何用Java实现抓取指定端口的数据包?(在线等待)
我这样写正则有问题吗?
一個關於jacob的問題,跪求援助!
关于java中如何编写email发送端???
如何通过程序在eclipse中判断一个文件是否保存。
从文件中读出一个Object,怎样知道这个Object具体是什么类型(有代码),只能用Instanceof吗?
UUID格式的验证
Java 如何通过 SNMP 获取 window 的信息呢?
java.util.Timer和java.util.TimerTask的迷惑