Re: [考題] 程式語言 96交通升資

看板Examination作者 ( )時間10年前 (2014/03/31 00:02), 10年前編輯推噓4(4038)
留言42則, 5人參與, 最新討論串2/3 (看更多)
此篇觀念為錯誤觀念 請勿參考 ※ 引述《okstephen1 (ㄌㄩㄝ)》之銘言: : [考題] 國考歷屆考題與考題觀念討論(書裡看到的選這個)請附上想法、出處 : int *f(int x) : { : int y; : y = x + 10; : return &y; : } : int g(int y) : { : int x; : x = y – 10; : return x; : } : void main( ) : { : int *x, y; : x = f(10); : y = g(*x); : printf(“%d %d\n”, *x, y); : } 活動記錄一開始是Main local y main local x ==>執行函數f dynamic link(指到main) return address(return to main) funtion value(指到local y的位址) local x 10 f local y 20 local x main local y ==>f返回main後 dynamic link(指到main) return address(return to main) funtion value(指到local y的位址) local x 10 f local y 20 紅色部分因函數執行結束已釋放 local x 指到f執行時local x的address 也就是*x=10 main local y ==>執行函數g dynamic link(指到main) return address(return to main) funtion value 10 local y 20 g local x 10 local x 此時指到g的local x(也是f執行時local x的address) 也就是*x=10 main local y 執行結束後return 10給Main中的y 由於兩個分別獨立且分別呼叫的函式 所以他們的參數和區域變數會共用相同位址 也就是函數f的參數x跟函數g的參數y用相同記憶體(中央堆疊) 函數f的區域變數y跟函數g的區域變數x用相同記憶體 因此當函數f執行完時 main中的x指到一塊記憶體其內容為10 且此記憶體後來又給了函數g中的區域變數x使用 也就是當執行函數g時 main中的x是指到函數g中的區域變數x 所以當函數g中把區域變數x改成10時 主程式的main的x指向的記憶體也會被改成10(同一塊) 我自己剛看這題也是看不懂 想很久 後來自己跑程式就了解了 以下程式 void A() { int a=10; //如果你改成int *a=new int(10); 那b印出來就是亂數了 //因為a就變成指到堆積區(heap)而不是中央堆疊(stack)的記憶體了 } void B() { int b; cout<<b; } int main() { A(); B(); } 結果會印出10 你把A中的a改成多少 b就是印出多少 相同的道理 有錯麻煩指正...我是自己看書沒人可以問是不是這樣思考是正解... -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.164.82.109 ※ 文章網址: http://www.ptt.cc/bbs/Examination/M.1396195361.A.087.html ※ 編輯: Sunofgod (218.164.82.109), 03/31/2014 00:13:07 ※ 編輯: Sunofgod (218.164.82.109), 03/31/2014 00:15:00

03/31 08:09, , 1F
嗯,我好意外...你的程式還真的可以跑xdddd
03/31 08:09, 1F

03/31 08:11, , 2F
不過我剛剛測了一下,我認為第一次f()結束時main裡面*x
03/31 08:11, 2F

03/31 08:16, , 3F
會是20,f()的y跟g()的x都是函數第一個宣告的LV,會用相
03/31 08:16, 3F

03/31 08:17, , 4F
同位址,所以main中的x也是用跟上面兩個一樣的位址
03/31 08:17, 4F

03/31 08:18, , 5F
你的程式如果a=10前面再宣告隨便一個LV就會印出那個值
03/31 08:18, 5F

03/31 08:19, , 6F
然後我不負責任發言..這已經超乎我的想像了..求高手...
03/31 08:19, 6F

03/31 11:06, , 7F
這就是你的想像阿 共用相同記憶體位址 我的程式跟這個
03/31 11:06, 7F

03/31 11:07, , 8F
題目是一樣的道理 只是我把他簡化了
03/31 11:07, 8F

03/31 11:09, , 9F
你說a=10前面再宣告一個區域變數 那就變成此區域變數和
03/31 11:09, 9F

03/31 11:09, , 10F
B中的b共用相同記憶體位址
03/31 11:09, 10F

03/31 11:28, , 11F
嗯嗯,不過最近才上PL的課,都是說LV記憶體用完會被釋放
03/31 11:28, 11F

03/31 11:29, , 12F
所以這種題目如果真的出來還是要寫...
03/31 11:29, 12F

03/31 11:33, , 13F
後來才想到釋放應該是指對副程式而言的確已釋放 即副程式
03/31 11:33, 13F

03/31 11:34, , 14F
不在擁有中央堆疊的記憶體空間 但中央堆疊的記憶體內容看
03/31 11:34, 14F

03/31 11:34, , 15F
來並不會被清掉
03/31 11:34, 15F

03/31 14:07, , 16F
int *a=new int(10); 這一行是指到stack區域嗎??
03/31 14:07, 16F

03/31 14:08, , 17F
這樣的話 我理解成 Y就變成全域變數了??是這樣嗎qq
03/31 14:08, 17F

03/31 14:12, , 18F
指到堆積區(heap) 不是堆疊(stack)
03/31 14:12, 18F

03/31 14:12, , 19F
跟全域變數完全沒關係
03/31 14:12, 19F

03/31 14:26, , 20F
那就是等全部函式執行完 只到heap中的變數全部歸還??
03/31 14:26, 20F

03/31 14:26, , 21F
那函式歸還後變數值會回到main??
03/31 14:26, 21F

03/31 14:29, , 22F
耶 我看不太懂你的意思 變數依照記憶體繫結方式分成好幾
03/31 14:29, 22F

03/31 14:32, , 23F
種 靜態繫結也就是全域變數或函式中的靜態變數會放在固定
03/31 14:32, 23F

03/31 14:33, , 24F
區;stack-dynamic variable也就是區域變數跟參數會放在
03/31 14:33, 24F

03/31 14:33, , 25F
堆疊區(中央堆疊);heap-dynamic variable也就是new指令
03/31 14:33, 25F

03/31 14:34, , 26F
在執行時動態分配的會放在heap區 此題主要是考函式呼叫
03/31 14:34, 26F

03/31 14:34, , 27F
故都會放在stack(中央堆疊的位置)
03/31 14:34, 27F

03/31 14:35, , 28F
根據執行結果 當函式執行結束 其與記憶體繫結結束
03/31 14:35, 28F

03/31 14:35, , 29F
但值仍然會保留在stack(中央堆疊)的位置 此時如果你有指
03/31 14:35, 29F

03/31 14:36, , 30F
向他依舊可以存取到 但我不知道這算不算前面版友說的懸疑
03/31 14:36, 30F

03/31 14:36, , 31F
指標.. 畢竟他是指到中央堆疊 不算指到作業系統的記憶體
03/31 14:36, 31F

03/31 14:38, , 32F
我的程式得註解只是我自己跑程式的心得 各位可以自己跑看
03/31 14:38, 32F

03/31 14:38, , 33F
看 甚至可以印出各變數的記憶體位置來比較看看 會更清楚
03/31 14:38, 33F

03/31 23:58, , 34F
謝謝sun大的指教 非常清楚
03/31 23:58, 34F

03/31 23:58, , 35F
推薦大家印出記憶體位置就一目瞭然
03/31 23:58, 35F

04/01 08:58, , 36F
我是覺得應該是釋放的記憶體未被分配使用 所以可讀出是10
04/01 08:58, 36F

04/01 09:00, , 37F
不然照理論說 應該會錯誤發生 因為活動紀錄被釋放
04/01 09:00, 37F

04/01 12:02, , 38F
應該也算懸疑指標 因為指向不具意義的記憶體
04/01 12:02, 38F

04/02 07:31, , 39F
多謝K大,所以說中央堆疊仍算是系統的記憶體囉?
04/02 07:31, 39F

04/02 11:20, , 40F
我想是吧 函式執行時 系統從堆疊分配記憶體空間給函式
04/02 11:20, 40F

04/02 11:23, , 41F
建立活動紀錄 執行完再釋放 印象中好像也有遇過類似題目
04/02 11:23, 41F

04/02 17:19, , 42F
非常感謝您!!
04/02 17:19, 42F
※ 編輯: Sunofgod (61.227.254.96), 04/18/2014 17:43:48
文章代碼(AID): #1JE40X27 (Examination)
文章代碼(AID): #1JE40X27 (Examination)