在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

當函數執行完畢后,如何返回調用處?

AGk5_ZLG_zhiyua ? 來源:未知 ? 作者:佚名 ? 2017-09-14 14:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

周立功教授數年之心血之作《程序設計與數據結構》以及《面向AMetal框架與接口編程(上)》,書本內容公開后,在電子行業掀起一片學習熱潮。經周立功教授授權,本公眾號特對《程序設計與數據結構》一書內容進行連載,愿共勉之。

第二章為程序設計技術,本文為2.3 棧與函數返回。

當函數執行完畢后,如何返回調用處呢?由于該函數可能會被多次調用,且每次調用的地方很可能不一樣,這樣被調用函數也就不可能知道自己該返回到哪里,因此在調用函數時必須告訴被調用函數應返回到哪里?

>>> 2.3.1 堆棧

為了保存變量(數據),通常計算機會提供非常多的內存。為了便于管理內存,將所有變量使用的內存稱為棧,而將未分配的內存區域稱為堆。這些未分配的內存區域,程序員可以塊為單位請求它。這部分內存是由操作系統管理的,一旦一塊內存被分配出去,它只能由分配了這塊內存的原始代碼使用,并使用指針訪問這塊內存。由于內存是稀缺資源,當程序不再需要該內存時,都應該釋放回去。如果不這樣做,程序將會耗光內存,導致運行速度下降甚至崩潰。這就是因為程序員沒有釋放本應釋放的內存,造成了所謂的內存泄漏。

堆和棧是兩種常用的數據結構,主要用于數據的動態存儲。當程序執行時,棧中存儲的是程序的執行過程,比如,main()函數的局部變量argc和argv都在棧中,而使用malloc()函數動態分配的內存是存儲在堆中的,堆棧共享同一塊內存區域。通常程序棧占據這塊區域的下部,而堆用的是上部。當調用函數時,函數的棧幀被推到棧上,棧向上“長出”一個棧幀。當函數終止時,其棧幀從程序棧彈出。雖然棧所使用的內存不會被清理,但最終可能會被推到程序棧上的另一個棧幀覆蓋。動態分配的內存來自堆,堆向下生長。隨著內存的分配和釋放,堆中會布滿碎片。盡管堆是向下生長的,但這只是大體方向,實際上內存可能在堆上的任意位置分配。

平常大家所說的“堆棧”主要是指棧,計算機在硬件上直接支持棧。在計算機科學中,棧是一個抽象的概念。它的抽象行為特征是棧可以存儲相同類型的數據,通常又將棧中的數據稱為元素。只允許向棧中壓入一個元素(即入棧push),或從棧中刪除一個元素(即出棧pop),且元素按照“后進先出”原則處理(last in,first out,LIFO),禁止測試或修改不在棧頂的元素。

圖2.7 四種棧示意圖

如圖2.7所示為通用計算機4種形式的棧,分別稱之為滿遞減堆棧、空遞減堆棧、滿遞增堆棧和空遞增堆棧,這些都是棧的物理結構。其中的“遞減”是指數據入棧時堆棧指針的值減少,即堆棧從高地址向下增長,就像鐘乳石一樣。“遞增”是指數據入棧時堆棧指針的值增加,即堆棧從低地址向上增長,就像石筍一樣。而“滿”是指SP指向的存儲單元保存最后入棧的數據;“空”是指SP指向的存儲單元將保存下一個入棧的數據。4種形式的棧都對應相同的邏輯數據結構,本書后續章節除非特殊說明,否則均以“滿遞增堆棧”為例。

>>> 2.3.2 入棧與出棧

假設允許入棧和出棧數據為int,即sp為(int *)類型變量。如果入棧的數據小于sizeof(int)個字節,則需要將其轉換成int類型數據才能入棧,且出棧后也要進行相應的類型轉換。對于入棧的數據大于sizeof(int)個字節,則只能拆分數據,一次入棧數據的一部分,通過多次入棧完成整個數據的入棧;而出棧這個數據也要多次,全部出棧后再組合成原始數據。

1. 入棧(push)操作

如果將sp當作(int *)類型的變量,則對于滿遞增堆棧來說,將數據data入棧用C語言描述如下(詳見圖2.8):

圖2.8 入棧操作示意圖

如果data的長度大于sizeof(int),則需要將數據拆分后多次入棧,入棧的順序可以先低位后高位,也可以反過來。如果入棧的順序為先低位后高位,其示例詳見程序清單 2.27。

程序清單 2.27 先低位后高位順序入棧示例

這里假設data可以象整數一樣移位,且sizeof(data)是sizeof(int)的4倍。

2. 出棧(pop)操作

如果將sp當作(int *)類型的變量,則對于滿遞增堆棧來說,將數據出棧用C語言描述如下(假設出棧的數據保存到變量data中,詳見圖2.9):

圖2.9 出棧操作示意圖

如果出棧數據data的長度大于sizeof(int),則需要多次出棧后拼接數據,其拼接的順序為入棧的反序。如果入棧的順序為先低位后高位,詳見程序清單 2.28。

程序清單 2.28 先高位后低位順序出棧示例

這里假設data可以象整數一樣進行位操作,且sizeof(data)是sizeof(int)的4倍。

>>> 2.3.3 函數的調用與返回

在討論ADT棧之前,首先看一種用于處理程序運行時的函數調用的系統棧。每當函數被調用時,系統首先創建一個稱作活動記錄或棧幀的結構,將其放在系統棧的棧頂。初始時,被調函數的活動記錄只包含一個指向前一個活動記錄的指針和一個返回地址。前一個活動記錄的指針指向調用函數的活動記錄,而返回地址包含的是函數調用結束后下一條執行語句的地址。因為在任何時刻只有一個函數被執行,所以被執行的函數就是活動記錄位于系統棧棧頂的函數。

如果該函數又調用其它函數,那么函數中的局部變量(靜態局部變量除外)及其參數也將加到其活動記錄中,然后為被調函數創建一個新的活動記錄并存放在系統棧棧頂的函數。當被調函數結束時,刪除該活動記錄。此時調用函數的活動記錄又位于系統棧的棧頂,繼續運行該函數。

C語言通過硬件棧保存函數的返回地址,被調用函數將返回地址出棧到程序計數器PC中,以返回到調用點,其示例代碼詳見程序清單2.29。

程序清單2.29 函數的調用與返回示例

對于程序清單2.29(10)來說,用C語言描述如下:

對于程序清單2.29(5)來說,用C語言描述如下:

由此可見,當調用函數時,將主程序代碼行的下一條指令的地址保存到棧中;當函數返回時,程序就會從棧中獲取該地址,并從那一點繼續向下執行。在函數調用了其它函數的情況下,將每一個返回地址都放到棧中;當函數結束時,就可以找到它們在棧中的地址。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 堆棧
    +關注

    關注

    0

    文章

    183

    瀏覽量

    20079

原文標題:周立功:棧與函數返回的應用

文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠電子】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    一文詳解python調用函數

    函數被定義,本身是不會自動執行的,只有在被調用后,函數才會被執行,得到相應的結果。但是在 Py
    發表于 10-01 10:45 ?980次閱讀

    如何查看及更改函數/函數塊的調用環境

    是循環執行一個功能塊被多個外部函數/函數調用時,我們應如何查看某一次調用時的內部變量呢?這
    的頭像 發表于 11-17 09:08 ?1430次閱讀
    如何查看及更改<b class='flag-5'>函數</b>/<b class='flag-5'>函數</b>塊的<b class='flag-5'>調用</b>環境

    代碼未從函數調用返回

    調用函數,但是調用我的配置時鐘函數時,它執行函數
    發表于 09-16 07:11

    調用TCPIP_DHCP_IsServerDetected()函數時總是返回0

    Harmony v1.09在DHCP客戶端模式下,在設備從DHCP服務器成功獲取IP地址之后,調用TCPIP_DHCP_IsServerDetected()函數時,它總是返回0。(傳
    發表于 04-06 14:37

    C++教程之函數的遞歸調用

    C++教程之函數的遞歸調用執行函數 f 的過程中,又要調用 f 函數本身,稱為
    發表于 05-15 18:00 ?35次下載

    高效的C編程之函數調用

    指令BL或MOV pc,lr一般只需要6個指令周期(ARM7上)。 在函數的入口和出口使用多寄存器加載/存儲指令LDM和STM(Thumb指令使用PUSH和POP)提高函數體的執行效率。 ARM體系結構過程
    發表于 10-17 16:49 ?6次下載
    高效的C編程之<b class='flag-5'>函數</b><b class='flag-5'>調用</b>

    淺談C語言return語句和main 函數返回

    函數中,如果碰到return 語句,那么程序就會返回調用函數的下一條語句執行,也就是說跳出函數
    發表于 05-10 10:53 ?5573次閱讀

    Python-函數的進階與遞歸

    在程序開發中,有時候,會希望一個函數執行結束,告訴調用者 **一個結果** ,以便調用者針對結果作后續的處理,
    的頭像 發表于 02-16 15:19 ?999次閱讀
    Python-<b class='flag-5'>函數</b>的進階與遞歸

    return-函數返回值是什么

    return關鍵字后接變量名或表達式可以將函數的計算結果返回調用處。變量或表達式等同于接收果汁、豆漿的杯子。如果函數沒有返回值,retur
    的頭像 發表于 02-23 10:52 ?1691次閱讀
    return-<b class='flag-5'>函數</b>的<b class='flag-5'>返回</b>值是什么

    什么是函數返回值?

    函數返回值是函數調用后,執行調用函數內代碼
    的頭像 發表于 04-04 17:21 ?5584次閱讀

    python定義函數調用函數的順序

    定義函數調用函數的順序 函數被定義,本身是不會自動執行的,只有在被
    的頭像 發表于 10-04 17:17 ?2070次閱讀

    python函數函數之間的調用

    中沒有調用執行y()函數,只是執行了return y。而y變量也沒有值,所以整個程序的返回值就為無結果。 3.2 第二種情況 程序代碼如下:
    的頭像 發表于 10-04 17:17 ?857次閱讀

    C語言函數返回1和返回0究竟哪個好?

    C語言函數返回1和返回0究竟哪個好? 在C語言中,很多函數需要返回一個值來表示函數是否成功
    的頭像 發表于 10-31 14:43 ?1396次閱讀

    怎么讓python執行執行

    在Python中,可以使用一些技術來確保程序執行完畢執行其他任務。下面將詳細介紹幾種方法。 一、使用阻塞方式執行程序 阻塞方式是最簡單的
    的頭像 發表于 11-29 15:09 ?4484次閱讀

    如何把兩個數據返回調用函數

    函數的處理結果包含兩個數據,如何把兩個數據返回調用函數? 第一種,把兩個數據封裝成一個結構體,函數返回
    的頭像 發表于 01-08 10:15 ?386次閱讀
    主站蜘蛛池模板: 免费观看黄色在线视频 | 精品视频69v精品视频 | 丁香婷婷网 | 韩国理论片2023现在观看 | 日日干干| 最近2018年中文字幕免费图片 | 干成人| 婷婷六月色 | 亚洲精品久久久久影 | 色婷婷久 | 日韩激情淫片免费看 | 精品一区二区三区免费爱 | аⅴ资源中文在线天堂 | 国产视频一二三 | 天天摸天天碰天天碰 | 26uuu另类欧美亚洲曰本 | 35pao免费视频 | 伊人网成人 | 亚洲综合伊人 | 男女交性视频免费播放 | 五月婷婷 六月丁香 | 天天狠天天透天干天天怕处 | 免费网站日本永久免费观看 | 色偷偷狠狠色综合网 | 97国产精品人人爽人人做 | 亚洲毛片儿 | 四虎永久免费在线观看 | 天天躁夜夜躁狠狠躁躁 | 欧美一级特黄乱妇高清视频 | 免费人成年激情视频在线观看 | 亚洲 自拍 欧美 综合 | 一级片影院 | 亚洲视频色 | www.97色| 日本欧美一区二区三区免费不卡 | 午夜亚洲国产 | 性欧美高清久久久久久久 | 国产三级日本三级在线播放 | 美女黄页黄频 | 午夜影视网站 | 超薄肉色丝袜精品足j福利 超黄视频在线观看 |