[心得] 有關return

看板b94902xxx作者 (運命のルーレット廻して)時間18年前 (2005/10/17 22:33), 編輯推噓10(1003)
留言13則, 12人參與, 最新討論串1/1
幫了幾個求助之後, 發現大家的一個大問題是: 到底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
恩,有看有推XD
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
GooooooooooooooooooooooooD
10/18 00:44, 9F

10/18 10:18, , 10F
提醒一下萬一分了兩次sum(4)出來 他們還是不一樣的喔:)
10/18 10:18, 10F

10/18 10:19, , 11F
詳情可以上p老師的ACP-DP會教怎麼運用更強大的影分身XD
10/18 10:19, 11F

10/18 10:25, , 12F
推~~強者風範! 謝謝指導
10/18 10:25, 12F

10/19 19:12, , 13F
可以轉到Sandbox嗎?
10/19 19:12, 13F
文章代碼(AID): #13KxO-Ht (b94902xxx)