Keil 函式內聯 inline

2021-08-17 02:56:49 字數 1218 閱讀 4821

內聯函式是指:當編譯器發現某段**在呼叫乙個內聯函式時,它不是去呼叫該函式,而是將該函式的**,整段插入到當前位置。這樣做的好處是省去了呼叫的過程,加快程式執行速度,但是因為把內聯函式拷貝了很多份,所以程式大小也變大了。

當我們在程式裡呼叫函式時,要花時間執行下面幾個步驟:

1. 保護現場,就是先將主調函式裡的函式呼叫返回後要執行的指令的位址壓入棧中儲存;

2. 把被調函式的形參和auto儲存型別的變數壓入棧區儲存,這一步壓入的所有變數所占有的儲存我們稱之為被調函式的資料現場;

3. 執行完被調函式之後,把被調函式資料現場釋放(出棧);

4. 把第1步壓入的指令位址出棧,即恢復現場,然後找到這個位址繼續執行。

因此要是程式中乙個函式被呼叫了許多次,那麼編譯系統需要來來回回的往返許多趟,產生棧記憶體建立和釋放的開銷時間,於是c++(c99)的編譯系統提供了乙個方法。在被調函式的定義前加乙個標誌(inline)告訴編譯系統,編譯系統看到這個標誌後,實際編譯出的可執行程式,就如同用函式體合理地置換了函式被呼叫處一樣,我們稱之為內聯機制。

內聯函式的工作過程:

當定義了乙個函式之後,編譯器會將其編譯成乙個指令集合。這個指令集合在程式執行的時候會出現在記憶體的**區里,並且在呼叫此函式時程式執行的位址會跳轉到這個指令集合的入口位址,當指令集合執行完後,再跳回到主調函式。換句話說,任何時候記憶體中只有乙個指令集,如果該函式被呼叫10次,則執行時就會跳轉到同一入口位址10次。

如果定義為inline函式,編譯器並不建立真實函式,內聯函式不僅同普通函式一樣經過檢查後儲存函式名稱、引數型別和返回值型別,還會把內聯函式的本體也一併存入符號表中,在之後的編譯過程中一旦遇到該函式被呼叫時會首先檢查呼叫是否合法,然後編譯器會將inline函式的指令集合(函式**)複製嵌入到主調函式中的呼叫位置,內聯函式的**就會直接替換函式呼叫,這樣就不需要函式呼叫的跳轉開銷了。如果函式被呼叫了10次,就相當於記憶體中就包含10個相同指令集合的拷貝,沒有一次呼叫。

了解了內聯函式是怎麼工作的,那麼內聯機制的優劣就好理解了。需要清楚的是,我們定義為inline函式只是建議編譯器進行內聯,而不是命令編譯器進行內聯,所以最後是不是內聯函式取決於編譯器。還有關鍵字inline必須與函式定義放在一起才能使函式成為內聯(最後由編譯器決定),僅放在函式宣告前面不起作用。因為inline是在編譯時展開,必須有實體,在編譯階段,編譯器看到inline標誌就會根據該函式體情況去判斷是否應該將該函式體定義為內聯。

因此決不決定把函式內聯,實際上是空間和時間上的博弈,函式內聯是典型的空間換時間的方法。

inline 內聯函式

一 inline關鍵字用來定義乙個類的內聯函式,引入它的主要原因是用它替代c中表示式形式的巨集定義。表示式形式的巨集定義一例 define expressionname var1,var2 var1 var2 var1 var2 為什麼要取代這種形式呢,且聽我道來 1 首先談一下在c中使用這種形式巨...

inline內聯函式

技術類筆試題50 都會問巨集與inline的區別,自己去找找看?1 巨集替換發生在預編譯 2 巨集函式 如果可以這麼叫的話 替換時不會檢查引數,inline函式會檢查 3 巨集一定會發生替換,inline貌似不是強制的,編譯器想不替換也沒關係 4 巨集替換時存在著一些不可避免的陷阱 參見c trap...

inline內聯函式

一 內聯函式 內聯函式是指用inline關鍵字修飾的函式 它與普通函式所不同之處只在於函式呼叫的處理。普通 函式進行呼叫時,要將程式執行權轉到被呼叫函式中,然後再返回到呼叫它的函式中 內聯函式不是在呼叫時發生執行權轉移,而是在編譯時將 函式 體 嵌入在每乙個呼叫處。編譯時類似巨集替換,使用 函式體替...