Re: [問題] 新手請教前置遞增運算子的問題

看板C_and_CPP作者 (朴髮箍)時間14年前 (2011/05/14 02:37), 編輯推噓1(101)
留言2則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《miyabichan (miyabichan)》之銘言: : int a = 4; : int funk1(int a){ : return(++a); : } : void proz(){ : ++a; : } : int funk2(int *a){ : return ((*a)++); : } : int main(){ : proz(); :   //printf("a = %d\n", a); : funk1(a); : printf("1: a = %d\n", a); : funk2(&a); : printf("2: a = %d\n", a); : getchar(); : return 0; : } 蠻不錯的例子 XD 你可以把每個函式想成一種小機器, 而你想觀察 的變數值則為它的輸入和輸出: (呼叫前的變數值) │ ┌─┴─┐ │函式名│ └─┬─┘ ↓ (呼叫後的變數值) 輸入不一定要透過給參數, 輸出不一定要回傳, 在這邊只關心某個 變數值在函式呼叫前/後的變化而已, 在你的例子就是全域變數 a 先作一個給你看(函式funk1為例): (呼叫前的變數值) │ ┌─┴─┐ │ funk1│ └─┬─┘ ↓ (呼叫後的變數值) 然後看一下它的程式碼: int funk1(int a){ return(++a); } 別太急著把它一行解決, 每一步寫得清楚點以確保你知道它究竟作 了哪些壞事: int funk1(int a){ int ret_value = a + 1; a = a + 1; return(ret_value); } 如果全域變數 a 的值在funk1()呼叫前是 10, 函式結束會變成 10 ,為什麼呢? 因為參數 a 掩蓋了全域變數 a, 所以在函式裡基本上 不會動到全域變數 a. 假設funk1()呼叫前全域變數 a 的值是 x, 函式結束後全域變數 a 的值還是 x,這樣就完成了我們的第一台小 機器: ( x ) │ ┌─┴─┐ │ funk1│ └─┬─┘ ↓ ( x ) 函式 proz() 對應到的小機器: ( x ) │ ┌─┴─┐ │ proz │ └─┬─┘ ↓ ( x + 1 ) 函式 funk2() 對應到的小機器: int funk2(int *a){ int ret_value = *a; *a = *a + 1; return ret_value; } 版本一: 版本二: (傳進全域變數a的位址) (傳進其他變數的位址) ( x ) ( x ) │ │ ┌─┴─┐ ┌─┴─┐ │ funk2│ │ funk2│ └─┬─┘ └─┬─┘ ↓ ↓ ( x + 1 ) ( x ) 你在 main 裡作的連續呼叫, 即是把上述這些小機器組裝起來:(尤 如生產線一般, 給材料就生產出成品) ( x ) │ ┌─┴─┐ │ proz │ └─┬─┘ ↓ ( x + 1 ) │ ┌─┴─┐ │ funk1│ └─┬─┘ ↓ ( x + 1 ) │ ┌─┴─┐ │ funk2│ (版本一) └─┬─┘ ↓ ( (x + 1) + 1 ) 把 a 的初始值 4 代入: ( 4 ) │ ┌─┴─┐ │ proz │ └─┬─┘ ↓ ( 5 ) │ ┌─┴─┐ │ funk1│ └─┬─┘ ↓ ( 5 ) │ ┌─┴─┐ │ funk2│ └─┬─┘ ↓ ( 6 ) 各階段產生的值就是你最後印出的結果了 (如果考慮到把回傳值接 起來的話會更複雜), 表達不好請見諒. 囧rz 我的建議是: 不要太早跳進去追蹤執行流程. 你可能會因為某些盲 點而身陷其中, 這時候跳出來當旁觀者會比較好. -- ▂▂ ▄▂ T.T.L Listen 2 http://ppt.cc/jIUk ˇ ˇˇ ˇ 說什麼結束 ▃▃ http://ppt.cc/zQtB ψ髮箍 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115

05/14 02:39, , 1F
文章排版,框架很棒 XD
05/14 02:39, 1F
※ 編輯: loveme00835 來自: 140.121.197.115 (05/14 04:33)

05/15 07:34, , 2F
很多顏色推
05/15 07:34, 2F
文章代碼(AID): #1DpNfLwF (C_and_CPP)
文章代碼(AID): #1DpNfLwF (C_and_CPP)