對不起,可能我沒表達清楚,我想問,數組作為參數傳入子函數為什麼不是作為形式參數傳入,請你看程序運行結果,如果數組作為形式參數傳入子函數,那麼形式參數的值並不會影響原來main函數中的值,但是實際上,main函數中數組原來的值已經被修改了,這是因為數組傳入的是地址(指針),我的問題就在這裡,傳入的是指針為什麼不是用完就扔的形式參數。
這與c語言的設計有關是嗎?內部有什麼機制嗎?
首先提一下std C 調用約定,參數的傳遞使用棧。
在傳遞時首先將參數按照反序壓棧,比如你有四個int參數 arg1 arg2 arg3 arg4,那麼他們會按照4 - 1的順序入棧。
接著將返回地址(當前pc值)入棧,然後將當前的輔助棧指針(ebp)入棧,接著設置輔助棧指針為當前棧指針 ebp = esp。
接著在子例程的內部使用ebp作為基准尋址參數。
接下來按照編譯器的設計會先為局部變量流出空間或者將會用到的寄存器入棧。
然後子例程的棧架構就建立了。這是尋址參數可以使用 ebp
棧的結構如下:
棧歷史 (地址高位)
arg4
arg3
arg2
arg1
pc
ebp
eax
ebx
ecx
...
為局部變量保存的空間
... (esp)(內存低地址)
尋址第一個變量就是在位置 ebp + 4 的位置上(arg1), 同理 arg2 --> ebp + 8, arg3 --> ebp + 12, arg4 --> ebp +16
再回來說數組為什麼不采用按值傳遞的問題。如果一個數組采用按值傳遞,將會在棧上為這個數組分配大量的空間,而棧空間是非常寶貴且有限的。
但是按引用傳遞就沒有這個問題。不論數組有多長,都只需要傳遞一個地址。棧空間內只需要保留一個地址的空間(4或8字節)即可。
特別是在單棧結構的處理器上,系統棧和進程棧使用同一個棧指針,按值傳遞將會很快耗盡棧空間,導致系統崩潰。
在雙棧設計的處理器上這個問題會好一些,但是也會導致當前進程崩潰。
對於一些安全性較差的系統,棧的溢出可能導致補課預料的讀寫了其他進程的空間,甚至是系統區。將會導致不可預知的後果。