Re: [問題] function的問題

看板C_and_CPP作者 (移動中...)時間10年前 (2014/03/25 17:57), 編輯推噓5(617)
留言14則, 7人參與, 最新討論串2/3 (看更多)
※ 引述《xshane831 (Shane)》之銘言: : 應該是基本的觀念問題,但我沒學好.. : 就是為何函式傳參數進去但沒有改變原始的值 : void dd(int x); : int main() : { 現在不開編譯器優化 倒出來的CPU母語該差不多是這樣 假設 int yes 在 EBP -8 : int yes=0; MOV EBX [EBP - 8] PUSH EBX call dd; /* 調用函數dd */ : dd(yes); ADD EPS, 4; 注意這行 ,離開函數後這位置被刷掉 也就是這值根本就是免洗的,只單純用來傳入函數 : cout<<yes; : return 0; : } : void dd(int x) : { PUSH EBP; MOV EBP ESP; MOV EAX, [EBP + 8]; : x=50+50; MOV EBX, 50; ADD EBX, 50; /*50 + 50*/ MOV [EBP + 8], EBX; /*[EBP + 8]即為int x*/ 看到了吧, 在函數內是把結果存在堆棧上 但這結果 在離開函數後 儲存的值,被當免洗內容刷掉了 (因為函數外的ESP管理不會干涉到函數內部) POP EBP; XOR EAX, EAX; RET; : } : 我認為最後yes應該要是100,但還是0,有改寫成 : void(int x, int y) : { : x=50+50 : y=x; : } : 並在main裡用另一個值yes2當第二個參數傳入,最終也沒改變 : 雖然改成int dd(int x)可以 : 而如果函式傳兩個以上參數且都需要回傳,改成return陣列也可以 : 但想知道為何不會改變原始傳進去的值,如: yes : 但用一些library,類似OpenCV,類似void cvSmooth(src, dst...) 就可 : 請問是為什麼? 我哪邊的觀念卡住了? : 感恩! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.176.104.49

03/25 19:53, , 1F
不認為這問題要用到組語才能校正觀念.
03/25 19:53, 1F

03/25 20:22, , 2F
感謝大大解說!
03/25 20:22, 2F

03/25 21:03, , 3F
雖然很詳細,但傳值都搞不清楚的人,組語能上手嗎...
03/25 21:03, 3F

03/25 22:08, , 4F
從組語來學 C/C++ , 這恐怕不是一般人做的事...
03/25 22:08, 4F

03/26 11:24, , 5F
這解釋倒果為因,參數值沒變是語言設計上的規範
03/26 11:24, 5F

03/26 11:25, , 6F
compiler產生的asm是為了遵守pass by value而產生的
03/26 11:25, 6F

03/26 11:32, , 7F
而不是「因為產生了這樣的asm所以它是pass by value」
03/26 11:32, 7F
※ 編輯: Move192 來自: 180.176.104.49 (03/26 14:45)

03/26 20:51, , 8F
C/C++有時還是需要用到組語概念
03/26 20:51, 8F

03/26 20:53, , 9F
像是非void函數漏掉return,必須以暫存器來解釋其行為
03/26 20:53, 9F

03/26 21:02, , 10F
--undefined behavior不用解釋啦(誤)--
03/26 21:02, 10F

03/26 22:22, , 11F
我會用語言設計不良來解釋,漏掉return根本不應該編過
03/26 22:22, 11F

03/26 22:26, , 12F
高階語言存在的目的就是提供一個抽象的模型去包裝底層
03/26 22:26, 12F

03/26 22:29, , 13F
對初學者來說底層asm怎麼跑根本就不是重點
03/26 22:29, 13F

03/26 22:29, , 14F
理解那個抽象模型才是最重要的
03/26 22:29, 14F
文章代碼(AID): #1JCLBnAZ (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1JCLBnAZ (C_and_CPP)