C語言中的堆和棧都是一種數(shù)據(jù)項按序排列的數(shù)據(jù)結(jié)構(gòu)。
公司主營業(yè)務(wù):做網(wǎng)站、網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出天全免費做網(wǎng)站回饋大家。
棧就像裝數(shù)據(jù)的桶或箱子
我們先從大家比較熟悉的棧說起吧,它是一種具有后進先出性質(zhì)的數(shù)據(jù)結(jié)構(gòu),也就是說后存放的先取,先存放的后取。
這就如同我們要取出放在箱子里面底下的東西(放入的比較早的物體),我們首先要移開壓在它上面的物體(放入的比較晚的物體)。
堆像一棵倒過來的樹
而堆就不同了,堆是一種經(jīng)過排序的樹形數(shù)據(jù)結(jié)構(gòu),每個結(jié)點都有一個值。
通常我們所說的堆的數(shù)據(jù)結(jié)構(gòu),是指二叉堆。堆的特點是根結(jié)點的值最小(或最大),且根結(jié)點的兩個子樹也是一個堆。
由于堆的這個特性,常用來實現(xiàn)優(yōu)先隊列,堆的存取是隨意,這就如同我們在圖書館的書架上取書。
雖然書的擺放是有順序的,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同于箱子,我們可以直接取出我們想要的書。
擴展資料:
關(guān)于堆和棧區(qū)別的比喻
使用棧就象我們?nèi)ワ堭^里吃飯,只管點菜(發(fā)出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。
參考資料來源:百度百科-堆棧
C語言函數(shù)參數(shù)入棧順序從右到左是為了方便可變參數(shù)函數(shù)。
一、在函數(shù)調(diào)用時,函數(shù)參數(shù)的傳遞,在C語言中是通過棧數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的。
在調(diào)用函數(shù)時,先根據(jù)調(diào)用函數(shù)使用的參數(shù),自右向左依次壓入棧中,然后調(diào)用函數(shù),在函數(shù)開始執(zhí)行時,將參數(shù)再依次彈棧。根據(jù)棧數(shù)據(jù)結(jié)構(gòu)先進后出的特點,在函數(shù)中彈棧的順序就是從左向右的。
二、對于參數(shù)固定的函數(shù),無論是從左向右還是從右向左,都沒什么區(qū)別,最終都是所有參數(shù)全部傳遞。
三、對于可變參數(shù),比如printf,會在第一個參數(shù)格式字符串中,指明后續(xù)有幾個參數(shù),各自是什么類型的。于是在函數(shù)中,參數(shù)格式字符串必須第一個彈棧,否則無法獲取參數(shù)類型,也就無法獲知后續(xù)參數(shù)占幾個字節(jié),導(dǎo)致無法正確獲知參數(shù)。
四、理論上來說,如果從左向右壓棧,可變參數(shù)標記格式字符串的參數(shù)放在最后,那么也是可以的。 不過最早設(shè)計C語言的人采用了這種方式,后續(xù)也就延續(xù)下來了。
程序的執(zhí)行過程可看作連續(xù)的函數(shù)調(diào)用。當一個函數(shù)執(zhí)行完畢時,程序要回到調(diào)用指令的下一條指令(緊接call指令)處繼續(xù)執(zhí)行。函數(shù)調(diào)用過程通常使用堆棧實現(xiàn),每個用戶態(tài)進程對應(yīng)一個調(diào)用棧結(jié)構(gòu)(call stack)。編譯器使用堆棧傳遞函數(shù)參數(shù)、保存返回地址、臨時保存寄存器原有值(即函數(shù)調(diào)用的上下文)以備恢復(fù)以及存儲本地局部變量。
不同處理器和編譯器的堆棧布局、函數(shù)調(diào)用方法都可能不同,但堆棧的基本概念是一樣的。
寄存器是處理器加工數(shù)據(jù)或運行程序的重要載體,用于存放程序執(zhí)行中用到的數(shù)據(jù)和指令。因此函數(shù)調(diào)用棧的實現(xiàn)與處理器寄存器組密切相關(guān)。
AX(AH、AL):累加器。有些指令約定以AX(或AL)為源或目的寄存器。輸入/輸出指令必須通過AX或AL實現(xiàn),例如:端口地址為43H的內(nèi)容讀入CPU的指令為INAL,43H或INAX,43H。目的操作數(shù)只能是AL/AX,而不能是其他的寄存器。 [5]
BX(BH、BL): 基址寄存器 。BX可用作間接尋址的地址寄存器和 基地址寄存器 ,BH、BL可用作8位通用數(shù)據(jù)寄存器。 [5]
CX(CH、CL):計數(shù)寄存器。CX在循環(huán)和串操作中充當計數(shù)器,指令執(zhí)行后CX內(nèi)容自動修改,因此稱為計數(shù)寄存器。 [5]
DX(DH、DL):數(shù)據(jù)寄存器。除用作通用寄存器外,在 I/O指令 中可用作端口 地址寄存器 ,乘除指令中用作輔助累加器。 [5]
2.指針和 變址寄存器
BP( Base Pointer Register):基址指針寄存器。 [5]
SP( Stack Pointer Register): 堆棧指針寄存器 。 [5]
SI( Source Index Register):源變址寄存器。 [5]
DI( Destination Index Register):目的變址寄存器。 [5]
函數(shù)調(diào)用棧的典型內(nèi)存布局如下圖所示:
圖中給出主調(diào)函數(shù)(caller)和被調(diào)函數(shù)(callee)的棧幀布局,"m(%ebp)"表示以EBP為基地址、偏移量為m字節(jié)的內(nèi)存空間(中的內(nèi)容)。該圖基于兩個假設(shè):第一,函數(shù)返回值不是結(jié)構(gòu)體或聯(lián)合體,否則第一個參數(shù)將位于"12(%ebp)" 處;第二,每個參數(shù)都是4字節(jié)大小(棧的粒度為4字節(jié))。在本文后續(xù)章節(jié)將就參數(shù)的傳遞和大小問題做進一步的探討。 此外,函數(shù)可以沒有參數(shù)和局部變量,故圖中“Argument(參數(shù))”和“Local Variable(局部變量)”不是函數(shù)棧幀結(jié)構(gòu)的必需部分。
其中,主調(diào)函數(shù)將參數(shù)按照調(diào)用約定依次入棧(圖中為從右到左),然后將指令指針EIP入棧以保存主調(diào)函數(shù)的返回地址(下一條待執(zhí)行指令的地址)。進入被調(diào)函數(shù)時,被調(diào)函數(shù)將主調(diào)函數(shù)的幀基指針EBP入棧,并將主調(diào)函數(shù)的棧頂指針ESP值賦給被調(diào)函數(shù)的EBP(作為被調(diào)函數(shù)的棧底),接著改變ESP值來為函數(shù)局部變量預(yù)留空間。此時被調(diào)函數(shù)幀基指針指向被調(diào)函數(shù)的棧底。以該地址為基準,向上(棧底方向)可獲取主調(diào)函數(shù)的返回地址、參數(shù)值,向下(棧頂方向)能獲取被調(diào)函數(shù)的局部變量值,而該地址處又存放著上一層主調(diào)函數(shù)的幀基指針值。本級調(diào)用結(jié)束后,將EBP指針值賦給ESP,使ESP再次指向被調(diào)函數(shù)棧底以釋放局部變量;再將已壓棧的主調(diào)函數(shù)幀基指針彈出到EBP,并彈出返回地址到EIP。ESP繼續(xù)上移越過參數(shù),最終回到函數(shù)調(diào)用前的狀態(tài),即恢復(fù)原來主調(diào)函數(shù)的棧幀。如此遞歸便形成函數(shù)調(diào)用棧。
EBP指針在當前函數(shù)運行過程中(未調(diào)用其他函數(shù)時)保持不變。在函數(shù)調(diào)用前,ESP指針指向棧頂?shù)刂罚彩菞5椎刂贰T诤瘮?shù)完成現(xiàn)場保護之類的初始化工作后,ESP會始終指向當前函數(shù)棧幀的棧頂,此時,若
本文標題:c語言函數(shù)棧 c語言函數(shù)棧調(diào)用
地址分享:http://www.chinadenli.net/article34/dohjose.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、網(wǎng)站設(shè)計公司、網(wǎng)站排名、品牌網(wǎng)站設(shè)計、建站公司、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)