c語言之堆疊溢位問題

2021-10-11 02:46:29 字數 2059 閱讀 3196

對於c來說,函式呼叫,系統要做三個工作:

這裡多提一下,關於陣列作為形參呼叫函式時,為什麼需要連同陣列長度一起傳進來?

這裡是因為,陣列作為引數傳遞的本質只是乙個指標,也就是乙個位址,編譯器並不關心這個位址後邊有多少有用資料,編譯器只看得到指標所指的資料。所以在被呼叫函式中,無法直接知道這個陣列的長度,所以當被呼叫函式想要使用陣列長度時,最方便就是將陣列長度作為形參傳遞進來,進而可以在傳進來的陣列的指標處依次往後讀取陣列長度個的資料。

函式呼叫時,系統記憶體通常分為**區、資料區和堆疊區,具體如下圖:

其中**區和常量儲存區屬於唯讀儲存區,用來存放程式**和部分常量;靜態儲存區用來存放外部變數和靜態區域性變數,堆區是程式進行動態分配管理的記憶體區域;棧區是在函式呼叫過程中存放函式區域性變數、函式引數和返回位址資訊的記憶體區域。堆區和棧區通常合稱為堆疊,屬於動態儲存區。

系統在進行函式呼叫時需要用到堆疊,堆疊是一種「後進先出」的資料結構。當程式呼叫乙個函式時,被調函式必須知道如何返回到主調函式,所以主調函式的返回位址必須壓入函式呼叫棧。如果發生了一系列的函式呼叫,其對應的一組返回位址將按照後進先出的順序壓入到函式呼叫棧,這樣每個函式才能正確的返回到它的主調函式。

函式的每次呼叫通常會產生一些區域性變數,這些區域性變數會儲存在函式呼叫棧中,這些資料被稱為函式呼叫的活動記錄。當發生一次函式呼叫時,它所對應的活動記錄將被壓入函式呼叫棧。當函式呼叫結束後返回到主調函式後,它對應的活動記錄將被彈出函式呼叫棧,儲存在其中的區域性變數將不能被程式所訪問。

函式呼叫棧中用來儲存活動記錄的儲存單元的總數有乙個上限,如果連續發生的多次函式呼叫產生的活動記錄超過了這一上限,將會發生堆疊溢位的錯誤。

遞迴函式就是直接或者通過其他函式間接的呼叫自己的函式。

下面以階乘的遞迴函式進行介紹,

int

fact

(int n)

在main函式中有fact(4)呼叫,函式遞迴求解的過程如下所示:

根據上面關於函式呼叫和記憶體管理的概念,每呼叫一次遞迴函式,系統就在棧區為該函式的相關資料分配相應的儲存空間,也就時入棧。當呼叫fact(4),會將fact(4),fact(3),fact(2),fact(1)的活動記錄依次入棧,當呼叫fact(1)時,返回值為1,此時函式呼叫結束,fact(1)出棧,返回到函式呼叫點也就是2fact(1);接著fact(2)出棧,返回值2返回到到函式呼叫點3fact(2);接著fact(3)出棧,返回值6返回到函式呼叫點4*fact(3);接著fact(4)出棧,返回值24返回到main函式呼叫點。

有了上面的理解,我們可以看出遞迴呼叫程式包括兩部分

遞迴函式的形式一般為:

if

(遞迴終止條件成立)

return 遞迴公式的初值;

else

return 遞迴函式呼叫返回的結果值;

設計遞迴函式的注意點

最近共同祖先應用案例

從圖中可以看出孩子和雙親的關係,如果雙親編號為i,則左孩子編號為2i,右孩子編號為2i+1。

在尋找兩個結點最近公共祖先的過程,每次讓比較大的數走向他們的雙親,直到他們相等,這個過程可以用遞迴實現:

int

common

(int x,

int y)

參考:

c語言程式設計(第二版)甘勇

ARM 堆疊溢位問題

今天一大早就有個師弟在qq上問了我乙個問題,先把 貼出來.softwareinterrupt stmfd sp mov r1,sp mrs r3,spsr tst r3,t bit thumb mode ldrneh r0,lr,2 yes,fetch swi no.in thumb mode bi...

C語言遇到的陣列溢位問題

今天寫了個判斷陣列中資料的最大值問題的 發現了乙個有趣的情況,陣列溢位值總是乙個 現附上今天寫的判斷陣列最大值的 define crt secure no warnings 1 include includeint main int max num 0 int i 0 for i 0 i sizeo...

c語言的算術運算溢位問題

1 關於溢位的結論 可能出現的情況是結果的資料型別定義的小了,導致結果不正確。關於計算溢位,看書上說的c語言中有符號數計算溢位的話會不知道發生什麼 溢位結果未定義 看編譯器怎麼處理。我在keil上試了下,溢位會把溢位部分砍掉,比如定義的是short型的,結果保留2個位元組。short aa 3276...