• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 20201023_081.遞歸函數_函數調用內存分析_棧幀的創建

    標簽: 學習筆記_Python編程基礎_Pycharm版

    遞歸函數

    遞歸函數指的是:自己調用自己的函數,在函數體內部直接或間接地自己調用自己。遞歸類似于大家中學數學學習過的“數學歸納法”。 每個遞歸函數必須包含兩個部分:

    1. 終止條件
      表示遞歸什么時候結束。一般用于返回值,不再調用自己。
    2. 遞歸邏輯關系
      把第 n 步的值和第 n-1 步相關聯。

    注意:遞歸函數會在棧中創建大量的函數對象,過量的消耗內存和運算能力,在處理大量數據時慎用。

    【案例】

    def test(n):
        print('test{}begin'.format(n))
        if n == 1:
            print(1)
        else:
            test(n - 1)
        print('test{}finished'.format(n))
        
        
    test(3)
    

    運行結果:
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vrk1tkyO-1603465725617)(en-resource://database/7411:0)]@w=120
    棧內存過程分析:
    最開始執行test(3),在test(3)函數里一行一行運行,過程中打印了結果的第1行:“test3begin”,判斷完n不=1,–>else: ,馬上要執行下一條代碼,棧里是這樣的
    在這里插入圖片描述
    所以運行test(2),這時test(3)還沒運行完。在tes(2)函數里一行一行運行,過程中打印了結果的第2行:“test2begin”,判斷完n不=1,–>else: ,馬上要執行下一條代碼,棧里是這樣的
    在這里插入圖片描述
    同理,運行test(1),這時test(3)、test(2)還沒運行完。棧里是這樣
    在這里插入圖片描述
    然后就在test(1)函數里一行一行運行,
    –>打印結果的第3行:“test1begin”,
    –>判斷n=1,打印結果的第4行:“1”,else的不執行了
    –>打印結果的第5行:“test1finished”
    然后test(1)就運行完了,test(1)占用的棧空間釋放掉,棧里變成了這樣
    在這里插入圖片描述
    然后繼續運行test(2)中剩下的代碼,打印結果的第6行:“test2finished”,打印完后,test(2)運行完,test(2)占用的棧空間釋放,棧里變成了這樣
    在這里插入圖片描述
    同理,接下來繼續運行test(3)中剩下的代碼,打印結果的最后一行,第7行:“test1finished”,打印完,test(3)也會運行完,釋放棧空間。接下來還會釋放掉定義test函數的棧空間(上面的圖沒畫),整個程序運行完成。

    版權聲明:本文為MinskyYi原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/MinskyYi/article/details/109251453

    智能推薦

    函數調用時,棧幀的創建與銷毀

    棧幀的創建與銷毀 這里我們寫一個簡單的加法函數來分析: 要研究函數的調用過程,我們需要用到對應的匯編代碼,見下圖(第一部分) 第一步:為main函數創建棧幀 首先棧幀的維護需要用到ebp和esp兩個寄存器 調用函數時,ebp指向棧底,esp指向棧頂 第二步:準備對Add函數的調用 對應的反匯編代碼(第二部分) 第三步:進入Add函數 對應的反匯編代碼(第三部分)...

    函數調用過程(棧幀的創建和銷毀)

    函數的調用過程 1. 調用 main() 函數: 2. Add() 函數的調用 在C語言中調用某一函數時,它會跳轉過去執行這個函數直到執行完畢后接著執行下一條指令。 在執行調用函數的過程中,通過形成一個棧幀來完成。棧幀是編譯器用來實現函數調用過程的一種數據結構。 以Add() 函數為例來分析調用過程: 棧幀的需要ebp和esp兩個寄存器。 在函數調用的過程中這兩個寄存器存放了維護這個棧的棧底和棧頂...

    函數調用過程,棧幀的創建和銷毀

    最初的棧結構 定義a,b 將b放在eax,將eax push入棧,esp下移 將a放在ecx,將ecx push入棧,esp下移 執行call命令,將當前正在執行的指令的下一條地址壓入棧中 執行call指令,通過jump命令跳轉到指定函數處,myadd函數的地址是00401020,則eip變為00401020 將mian函數的ebp壓入棧底,mov ebp,esp 形成一個新空間myadd函數的棧...

    函數調用過程,棧幀的創建和銷毀

      原碼如下: 基本的匯編指令: esp:esp寄存器里存儲的是在調用函數之后,棧的棧頂。并且始終指向棧頂。 ebp:ebp寄存器里存儲的是是棧的棧底指針,通常叫棧基址,這個是一開始進行函數調用之前,由esp傳遞給ebp的。(在函數調用前你可以這么理解:esp存儲的是棧頂地址,也是棧底地址。) push:壓入操作,把一個32位的操作數壓入堆棧中,這個操作在32位機中會使得esp被減4(字...

    函數調用過程中的棧幀分析

    說到函數棧幀,就不得不提到另外一個名詞“棧”,棧的主要特點:先入后出,后入先出(就像疊羅漢一樣),增長的方向,高地址向低地址生長,系統自動回收 那么棧幀是什么呢? 棧幀首先是存儲在棧上,棧幀記錄函數調用過程的一些信息的,例如變量、上一級棧幀的幀指針、函數的返回地址等,一個程序不止一個函數,很多時候都是函數的嵌套調用,那么棧上面肯定有多個棧幀(棧溢出因為棧空間不夠,棧幀太多會...

    猜你喜歡

    函數調用——棧幀

    在函數調用里面,有一個重要的過程,就是棧幀的調用,我簡單的介紹下棧幀的調用過程。 先用一段簡單的代碼來了解下棧幀的調用過程: 先調用下堆棧的使用: 下面就來看看main函數堆棧的調用: 我們發現其實main函數在 __tmainCRTStartup 函數中調?用的,而 __tmainCRTStartup 函數是 在 mainCRTStartup 被調?用的。 我們知道每?一次函數調?用都是?一個過...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡