作者LPH66 (运命のルーレット廻して)
看板b94902xxx
标题[心得] 有关return
时间Mon Oct 17 23:10:34 2005
帮了几个求助之後,
发现大家的一个大问题是:
到底return会回到哪里去?
我们先用一个简单的函数呼叫的例子来看好了:
void a(int x);
int b(int y);
int main(void)
{
int c;
a(5);
/*[A]*/
printf("a returns %d\n",c);
return 0;
}
void a(int x)
{
int d;
printf("%d + %d = %d\n",x,x,x+x);
d=b(x);
/*[B]*/
printf("b returns %d\n",d);
return;
}
int b(int y)
{
printf("%d * %d = %d\n",y,y,y*y);
return y+5;
}
好,我们在main呼叫了a(5);
然後a里面呼叫了b(x);
然後b做完,return了一个值,
请问b的return会回到哪里?
1. main的开始
2. a的开始
3. b的开始
4. 标[A]的地方
5. 标[B]的地方
6. 以上皆非
.
.
.
.
答案是5. 标[B]的地方。
所谓return, 就是回到
呼叫自己的那个人的地方,
也就是说
刚刚谁呼叫我,现在我做完了,换你继续。
因此,在上面这个例子中,呼叫b()的是标[B]的地方那个人(就是a),
於是这里的return就回到那边去。
同理,a()的return所回到的地方,就是叫a()的那个人,也就是标[A]的地方。
那这里a它return给main什麽呢? 一个讯息: a我已经做完了,你可以继续做。
现在来看递回呼叫的情形:
int main(void)
{
int s;
s=sum(5);
/*[C]*/
printf("sum of 1 to 5 is %d.\n",d);
return 0;
}
int sum(int x)
{
if(x==1)
return 1;
else
return x+sum(x-1);
/*[D]*/
}
在这个情形中,sum自己呼叫自己,
所以有人就搞混了: 到底sum的return会回到哪里去?
是回到[C]? 还是回到[D]?
答案是: 要看是谁叫他们的。
在上面的例子中,main在[C]的地方先呼叫了一个sum(5),
於是sum就跳了一个分身出来叫sum(5),来处理main的呼叫。
然後sum(5)看到要他算5+sum(4),所以在[D]的地方呼叫了sum(4),
这个时候sum又跳了一个分身出来叫sum(4),来处理sum(5)的呼叫。
然後sum(4)看到要算4+sum(3),又呼叫了sum(3),
所以sum又跳了sum(3)这个分身出来,
sum(3)要算3+sum(2),呼叫sum(2),sum跳出sum(2)分身,
sum(2)要算2+sum(1),呼叫sum(1),sum再跳出sum(1)分身,
最後sum(1)看到自己要算的是1,这他可以算,
然後他要把这个值return回去。return给谁呢?
sum(1)看一看是谁叫他的。是sum(2),所以他把这个值给了sum(2)。
sum(2)看到他要的sum(1)已经算好给他了(是1),
於是他就算他的2+sum(1)=2+1=3。
算好了要return,return给谁? sum(2)看谁叫他的。是sum(3),所以他把3给了sum(3)。
就这样一直算,一直return,到最後sum(5)终於完成了他的任务,算出答案(15),
然後他也要return,这次他看到是main叫他的,所以他把15给了main。
main得到答案15 就高兴的printf出来: sum of 1 to 5 is 15.
这样子各位有比较了解return到底回到哪里去了吗?
使徒四的密技中,助教这样写:
: if (不是数字0) {
: 往下试;
: } else {
: 记录已经被使用过的数字(行, 列, local九宫格);
: for each available number i do
: {
: 填 i;
: 往下试;
: 填回 0;
: }
: }
这所谓的"往下试",其实就是叫另一个分身出来去试着填下一个位置。
那分身要怎麽告诉你後面是有路还是没路呢?
这就是分身的return。
如果我们这样设定: 只要我找到答案了,直接印答案之後结束程式,
那我们在函数最後(确定此後没路了)写上return;
那麽当分身试完,发现没路了,
他就会告诉上一个分身: "我这里已经确定没路了,你可以继续试下一个",
叫人的分身知道了後面没路,自己就换一下填的数字,再叫那个分身出来试试看。
如果在後面分身处理没路时,你又叫了一个分身出来,告诉他处理前面,
新叫的分身可不会知道原来的分身做了什麽,他会重头开始做,
所以就会一直呼叫呼叫……,
到最後查克拉(stack)不够就会累挂了(stack overflow)。
这样有比较清楚要怎麽做了吗?
--
"LPH" is for "Let Program Heal us"....
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.240.54
1F:推 alex1025:虽然我是双班的~你写的很清晰易懂~连我这个弱者都看的懂. 10/17 23:14
2F:推 NeantD:推 10/17 23:24
3F:→ yjpetergto:推..这个问题困扰了我好久...谢谢 10/17 23:26
4F:推 frankfbo:看了怎可不推~ 10/17 23:48
5F:推 IamrealBB:恩,有看有推XD 10/17 23:55
6F:推 sa033766:高手 推 10/17 23:55
※ 编辑: LPH66 来自: 140.112.240.54 (10/18 00:03)
7F:→ LPH66:囧 我发现我忘了加还原码 已经加上去了 10/18 00:03
8F:推 SadCrusader:推~~~~~ 10/18 00:21
9F:推 hamigwa:GooooooooooooooooooooooooD 10/18 00:44
10F:推 springgod:提醒一下万一分了两次sum(4)出来 他们还是不一样的喔:) 10/18 10:18
11F:→ springgod:详情可以上p老师的ACP-DP会教怎麽运用更强大的影分身XD 10/18 10:19
12F:推 anauma:推~~强者风范! 谢谢指导 10/18 10:25
13F:推 pangfeng:可以转到Sandbox吗? 10/19 19:12