一般函式呼叫原理:
執行到函式呼叫指令時,程式將在函式呼叫後立即儲存該指令的記憶體位址,並將函式引數複製到堆疊(為此保留的記憶體塊),跳到標記函式起點的記憶體單元,執行函式**(也許還需將返回值放入暫存器中),然後跳回到位址被儲存的指令處。來回跳躍並記錄跳躍位置意味著以前使用函式時,需要一定的開銷。
內聯函式提供了另一種選擇。編譯器將使用相應的函式**替換函式呼叫。因此,內聯函式的執行速度比常規函式稍快,但代價是需要占用更多記憶體。內聯函式在編譯階段,將f0的**拷貝到f1的指定位置,在f1()函式呼叫普通函式f0()時,不需要函式位址的轉移以及壓棧出棧、保護現場等操作。
內聯函式的優點和缺點:
優點:對於一些較小的函式,如果頻繁呼叫,可以將其設計為內聯函式,省去了執行函式位址轉移等操作,占用系統資源更少,執行效率更高。
缺點:如果呼叫內聯函式的地方太多,就會造成**膨脹,因為編譯器會把每個呼叫內聯函式的位置都拷貝乙份函式實現嵌入其中,重複的嵌入。
這點有點類似於結構體指標和結構體:結構體指標是乙個指標,也就是結構體的位址,結構體變數是一段記憶體區域。在執行淺拷貝時,結構體指標拷貝的是8個位元組的指標,結構體變數拷貝則拷貝整個記憶體區域。可能造成所佔記憶體的增加,占用系統資源比指標多。
內聯能提高函式的執行效率,為什麼不把所有的函式都定義成內聯函式?如果所有的函式都是內聯函式,還用得著「內聯」這個關鍵字嗎?
內聯是以**膨脹(複製)為代價,僅僅省去了函式呼叫的開銷,從而提高函式的執行效率。如果執行函式體內**的時間,相比於函式呼叫的開銷較大,那麼效率的收穫會很少。另一方面,每一處內聯函式的呼叫都要複製**,將使程式的總**量增大,消耗更多的記憶體空間。
慎用內聯
以下情況不宜使用內聯:
(1)如果函式體內的**比較長,使用內聯將導致記憶體消耗代價較高。
(2)如果函式體內出現迴圈,那麼執行函式體內**的時間要比函式呼叫的開銷大。
乙個好的編譯器將會根據函式的定義體,自動地取消不值得的內聯(這進一步說明了inline 不應該出現在函式的宣告中)。
內聯函式與巨集定義的區別:
使用巨集和內聯函式都可以節省在函式呼叫方面所帶來的時間和空間開銷。二者都採用了空間換時間的方式,在其呼叫處進行展開: (1) 在預編譯時期,巨集定義在呼叫處執行字串的原樣替換。在編譯時期,內聯函式在呼叫處展開,同時進行引數型別檢查。 (2) 內聯函式首先是函式,可以像呼叫普通函式一樣呼叫內聯函式。而巨集定義往往需要新增很多括號防止歧義,編寫更加複雜。 (3) 內聯函式可以作為某個類的成員函式,這樣可以使用類的保護成員和私有成員。而當乙個表示式涉及到類保護成員或私有成員時,巨集就不能實現了(無法將this指標放在合適位置)。
可以用內聯函式完全替代巨集。 在編寫內聯函式時,函式體應該短小而簡潔,不應該包含迴圈等較複雜結構,否則編譯器不會將其當作內聯函式看待,而是把它決議成為乙個靜態函式。
有些編譯器甚至會優化內聯函式,通常為避免一些不必要拷貝和構造,提高工作效率。
C 內聯函式
1 什麼是內聯函式?內聯函式就是小型函式,犧牲空間來節省函式呼叫的開銷,一般用作比較小的函式,即函式內部沒有迴圈 開關語句等。內聯函式被發明出來就是為了取代c中的巨集,因為巨集是單純的替換而沒有型別檢查所以經常出毛病,2 為什麼要引入內聯函式?當然,引入內聯函式的主要目的是 解決程式中函式呼叫的效率...
C 內聯函式
1 什麼是內聯函式?2 為什麼要引入內聯函式?3 為什麼inline能取代巨集?4 內聯函式和巨集的區別?5 什麼時候用內聯函式?6 如何使用內聯函式?7 內聯函式的優缺點?8 如何禁止函式進行內聯?9 注意事項 1 什麼是內聯函式?內聯函式是指那些定義在類體內的成員函式,即該函式的函式體放在類體內...
c 內聯函式
1 什麼是內聯函式?內聯函式是指那些定義在類體內的成員函式,即該函式的函式體放在類體內。2 為什麼要引入內聯函式?當然,引入內聯函式的主要目的是 解決程式中函式呼叫的效率問題。另外,前面我們講到了巨集,裡面有這麼乙個例子 define abs x x 0?x x 當 i出現時,巨集就會歪曲我們的意思...