[心得] 有關return
幫了幾個求助之後,
發現大家的一個大問題是:
到底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
推
10/17 23:14, , 1F
10/17 23:14, 1F
推
10/17 23:24, , 2F
10/17 23:24, 2F
→
10/17 23:26, , 3F
10/17 23:26, 3F
推
10/17 23:48, , 4F
10/17 23:48, 4F
推
10/17 23:55, , 5F
10/17 23:55, 5F
推
10/17 23:55, , 6F
10/17 23:55, 6F
※ 編輯: LPH66 來自: 140.112.240.54 (10/18 00:03)
→
10/18 00:03, , 7F
10/18 00:03, 7F
推
10/18 00:21, , 8F
10/18 00:21, 8F
推
10/18 00:44, , 9F
10/18 00:44, 9F
推
10/18 10:18, , 10F
10/18 10:18, 10F
→
10/18 10:19, , 11F
10/18 10:19, 11F
推
10/18 10:25, , 12F
10/18 10:25, 12F
推
10/19 19:12, , 13F
10/19 19:12, 13F