一、 常量與巨集回顧
c++中的const常量可以替代巨集常數定義,如:
const int a = 3;等價於 #define a 3
那麼c++中是否有解決方案替代巨集**片段呢?請看以下內容。
二、 內聯函式的定義
(1)c++中推薦使用內聯函式替代巨集**片段;
(2)c++中使用inline關鍵字宣告內聯函式;
(3)內聯函式宣告時inline關鍵字必須和函式定義結合再一起,否則編譯器會直接忽略內聯請求。內聯函式的定義如圖1所示:
三、 內聯函式的特點
(1)c++編譯器可以將乙個函式進行內聯編譯,被c++編譯器內聯編譯的函式叫做內聯函式;
(2)c++編譯器直接將函式體插入函式呼叫的地方;
(3)內聯函式沒有普通函式呼叫時的額外開銷(壓棧,跳轉,返回);
(4)c++編譯器不一定滿足函式的內聯請求;函式的內聯請求可能被編譯器拒絕;
(5)內聯函式具有普通函式的特徵(引數檢查,返回型別等 );
(6)巨集**片段由預處理器處理,進行簡單的文字替換 ,沒有任何編譯過程,因此可能出現***。
如圖2所示的**,用情況1編譯後的執行結果如圖3所示;這就是巨集**出現的***,情況1的文字替換後如圖 4所示:
用圖2**的情況2編譯執行後的結果如圖5所示,這個就和分析的一樣,因此內聯函式不會產生***。
用圖2**的情況2在vs2015的預設編譯後的彙編**如圖6所示;從圖6中可以看到有函式的呼叫,說明inline的內聯請求被拒絕了;這是因為編譯器的優化功能沒有被設定。編譯器的優化功能設定如圖7所示,經過設定了編譯器的優化功能後,編譯後的彙編**如圖8所示,從圖8中可以到沒有函式呼叫了,而是將函式體插入函式呼叫的地方。
四、 現代c++編譯器對內聯函式的優化
(1)現代c++編譯器能夠進行編譯優化 ,一些函式即使沒有inline宣告,也可能被內聯編譯。
(2)一些現代c++編譯器提供了擴充套件語法,能夠對函式進行強制內聯,如圖9的**和如下所示:
a) g++:__attribute__((always_inline))屬性
五、 c++中inline內聯編譯的限制
(1)不能存在任何形式的迴圈語句;
(2)不能存在過多的條件判斷 語句;
(3)函式體不能過於龐大;
(4)不能對函式進行取位址操作;
(5)函式內聯宣告必須在呼叫語句之前。
六、 內聯函式、巨集和帶引數函式三者的比較
內聯函式的優點:函式**被裝入符號表中,在使用時進行替換沒有呼叫開銷,效率高,會進行引數型別檢查。
內聯函式的缺點:函式**較長,使用內聯將消耗過多記憶體;
函式體內有迴圈,執行**的時間比較長。
巨集的優點:原地展開,沒有呼叫開銷;
並且在預處理階段完成,不占用編譯時間。
巨集的缺點:不進行型別檢查,多次巨集替換會導致**體積變大;
一些引數的***會導致得出錯誤的結果。
帶參函式的優點:編譯器會做引數的靜態型別檢查。
帶參函式的缺點:需要傳參、棧變數的開闢和銷毀;
壓棧、跳轉、返回開銷;
第6課 內聯函式分析
帶參函式巨集內聯函式 優點編譯器會做引數的靜態型別檢查 原地展開,沒有呼叫開銷 並且在預處理階段完成,不占用編譯時間。函式 被裝入符號表中,在使用時進行替換 沒有呼叫開銷,效率高,會進行引數型別檢查 缺點需要傳參 棧變數的開闢和銷毀 壓棧 跳轉 返回開銷 不進行型別檢查,多次巨集替換會導致 體積變大...
C 第6課 內聯函式分析
本文學習自 狄泰軟體學院 唐佐林老師的 c 課程 引入 c 內聯函式的引入是為了替換c中巨集 塊功能 實驗1 巨集 塊 vs 內聯函式 注意 在c 開發中首選內聯函式定義 塊,而不是巨集實驗2 強制內聯 c語言中的巨集常量只是在預處理期間進行鍵的文字替換,它的 是並不會進行任何的語法檢查,型別檢查。...
inline函式 C 內聯函式 inline
inline要起作用,必須要與函式定義放在一起,而不是函式的宣告 inline 當編譯器處理呼叫內聯函式的語句時,不會將該語句編譯成函式呼叫的指令,而是直接將整個函式體的 插人呼叫語句處,就像整個函式體在呼叫處被重寫了一遍一樣,在執行時是順序執行,而不會進行跳轉。優點 內聯函式沒有執行函式呼叫的開銷...