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

看板C_and_CPP作者 (miyabichan)時間14年前 (2011/05/14 01:20), 編輯推噓2(2032)
留言34則, 7人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) windows, 很簡單的用notepad++做編輯,compile用 lcc-win32 問題(Question): 前置遞增運算子 + function 內 return 程式碼(Code):(請善用置底文網頁, 記得排版) #include <stdio.h> 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; } 我們必須畫出 Zeigerdiagramm(就是變數會指到一個reference, 再指到 value 的圖) 我畫完之後的結果會是,在呼叫完 funk1(a) 後,a 會等於 6, 呼叫完 funk2(&a) 後,a 會等於 7.. 可是打進程式編碼完後執行的結果都少一, 所以我在呼叫 proz() 後增加一個 print out 來檢查我的觀念是哪裡有問題, proz() 呼叫完後 a=5,所以我的問題應該是在 return(++a) 這裡。 請問為什麼不是 return 6 而是 return 5 呢? 是因為 funk1 先把 5 return 給全區變數的那個 a 以後,自己的 a 再加一嗎? (然後跳出 function 後他自己的 a 裡的值就被清掉了?) -- 不好意思,我這些東西都是用德文學的, 然後再盡我所能的翻成英文,因為很多東西我不知道怎麼用中文講。 麻煩大家了,謝謝<(_._)> -- ╔╦╩CSILVGREG SANDERS╠□╦╩╬╦╠╦●╩═ ╬◆╠╬╠╬╦☆═╦╬█╗ ╠ ╭═══╮╭═══╮╔═══╗葛瑞格.山德斯(Greg Sanders) [n.][a.][v.] ╬ ║ ╭═╯║ ╰╯╚═╗╔╝ 【n.】LV 夜班寵物兼鑑識員跟實驗室檢定人員 ◆ ║ ╰╯║╭═╮ ║╔═╝╚╗ 【a.】調皮的;歡樂的;情緒明顯的;興趣多廣的 ╣ ╰═══╯╰═══╯╚═══╝ 【v.】不懂得時機說話;表現後期待主人稱讚 ╩╬╦╗☆╩═╚╣╔╦╝╬╩║╣╦■╦╗╠╬╣☆╩╝╬◇╠╗╦╬╩╬阿皮ψ╦╣ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 217.87.229.105

05/14 01:26, , 1F
b=++a和b=a++ 不同
05/14 01:26, 1F
這個我懂,b=++a 是先算 a=a+1 後再做 b=a,   b=a++ 則是b=a+1,a 則仍是原來的值沒有變動。 我想問的是,為什麼 return(++a) 後, 全區變數的 a 仍是 5 而不是 6? ※ 編輯: miyabichan 來自: 217.87.229.105 (05/14 01:31)

05/14 01:36, , 2F
應該是全域變數和區域變數問題,函數內的變數離開就死了...
05/14 01:36, 2F

05/14 01:38, , 3F
c裡面傳值呼較,函數回傳的的值是被份,不會影響本來要傳進
05/14 01:38, 3F

05/14 01:39, , 4F
你的全域變數的名稱 不要跟 函數引數or區域相同...
05/14 01:39, 4F

05/14 01:39, , 5F
去的值.估狗一下call by vlaue 和call by reference就了解
05/14 01:39, 5F

05/14 01:39, , 6F
我想是因為funk1(a) 傳值呼叫,你認為a值會改掉但其實因為
05/14 01:39, 6F

05/14 01:40, , 7F
這是老師出的題目,我弄不懂為什麼return原先的值
05/14 01:40, 7F

05/14 01:40, , 8F
給參數弄一個副本所以不會動到原來參數.
05/14 01:40, 8F

05/14 01:40, , 9F
原本傳進去的a先備份一份,所以函數內是對被份的a作++,本來
05/14 01:40, 9F

05/14 01:40, , 10F
的a當然不受影響...
05/14 01:40, 10F

05/14 01:41, , 11F
而且b=a++ a仍然會+1..
05/14 01:41, 11F

05/14 01:43, , 12F
你是用zeigerdiagramm整理程式動線,那麼我想你要重想一下
05/14 01:43, 12F

05/14 01:43, , 13F
遇到函數呼叫的zeigerdiagramm
05/14 01:43, 13F

05/14 01:43, , 14F
funk2是 call by pointer....
05/14 01:43, 14F

05/14 01:50, , 15F
敘述邏輯也會講變數的binding,你可以融會貫通一下.
05/14 01:50, 15F

05/14 01:56, , 16F
@deh3215, yauhh:可是他不是有做 return 嗎?
05/14 01:56, 16F

05/14 01:58, , 17F
還是我的問題出在,我以為他有return就會傳值回去?!
05/14 01:58, 17F

05/14 01:58, , 18F

05/14 02:01, , 19F
我想我懂了!函數內有return,可是main裡沒有指定一個
05/14 02:01, 19F

05/14 02:01, , 20F
return 是指流程的移動,從函數內移回來. 但值的改變是另外一
05/14 02:01, 20F

05/14 02:02, , 21F
變數去接收return的值,所以funk1裡的++a做完運算以後
05/14 02:02, 21F

05/14 02:02, , 22F
沒有丟給任何一個變數,所以全域的 a 的值當然不會變
05/14 02:02, 22F

05/14 02:03, , 23F
對嗎?
05/14 02:03, 23F

05/14 02:04, , 24F
可以這麼說。仔細看會發現這小段程式碼的梗還真多...XD
05/14 02:04, 24F

05/14 02:04, , 25F
回事. 不曉得你老師有沒有提到函數內外變數同名時的情況
05/14 02:04, 25F

05/14 02:05, , 26F
對,funk1函數參數名字跟全域a同名,原本的全域關係就改變了
05/14 02:05, 26F

05/14 02:07, , 27F
@yauhh:我們學校重點放在java, c的部份老師打算用四堂
05/14 02:07, 27F

05/14 02:08, , 28F
課解決。java我知道用this可以解決問題,c就沒提到了
05/14 02:08, 28F

05/14 02:09, , 29F
@james732:你加一句話解釋我的疑問,感謝!
05/14 02:09, 29F

05/14 02:13, , 30F
java版:http://pastie.org/1897677 其實觀念一樣 XD
05/14 02:13, 30F

05/14 02:16, , 31F
感覺是很操勞的一門程式課程
05/14 02:16, 31F

05/14 02:42, , 32F
@james732: 可以用 Integer
05/14 02:42, 32F

05/14 02:52, , 33F
我聽過 VB PHP C++ 一學期上完的課...
05/14 02:52, 33F

05/14 05:10, , 34F
如果是用 GCC, 加上 -Wshadow 可以偵測到這個問題 =p
05/14 05:10, 34F
文章代碼(AID): #1DpMXqGu (C_and_CPP)
文章代碼(AID): #1DpMXqGu (C_and_CPP)