巨集與內聯函式

2021-06-09 14:09:38 字數 1714 閱讀 7651

函式作為一種抽象機制,對解決大型複雜問題起到了很大作用。但是,由於函式呼叫時需要開銷的,例如,函式呼叫時需要保護呼叫者的執行環境,進行引數傳遞,執行呼叫命令,為區域性變數分配空間以及執行返回指令等,因此函式會帶來程式執行效率的下降,特別是對一些小函式的頻繁呼叫。

c++提供了兩種解決上述問題的辦法:巨集定義和內聯函式。

1.巨集定義

巨集定義是c++的一種編譯預處理命令,它用#define來實現。在c++中,巨集定義有4中格式:

(1)#define  巨集名  文字串

如:#define  pi  3.1415

在編譯前,把程式文字中出現「巨集名」的地方用「文字串」進行替換,它主要用於符號常量的定義。

(2)#define  巨集名(參數列)   文字串

如:#define max(a,b)  a>b?a:b

int main()

替換後進行編譯,避免了函式呼叫所需開銷。這種巨集定義主要解決對小函式頻繁呼叫效率不高的問題。巨集定義是純粹的文字替換,如要運算10+max(x,y)+z ;替換後是10+x>y?x:y+z ;根據運算子的優先順序,它的含義是(10+x)>y?x:(y+z) ; 顯然不是我們所要的;因此我們應盡量給巨集定義中所有引數帶上括號,如:#define max(a,b)  (((a)>(b))?(a):(b)) 

(3) #define 巨集名

該巨集定義只是告訴編譯程式該「巨集名」已被定義,它並不做任何程式文字替換,其作用是實現條件編譯。

(4) #undef 巨集名

取消某個巨集名的定義,其後的「巨集名」不在進行程式文字替換和不在有定義。

2.內聯函式

巨集定義是c++從c中保留下來的,雖然它可以解決函式呼叫效率不高的問題,但它也存在一些不足:

(1) 有時會出現重複計算,例如對於上面的巨集定義:max(i++ , j++)  編譯預處理系統會把它替換成

(((i++)>(j++))?(i++):(j++)) 不管i++還是j++大,i++或j++都會被計算兩次

(2) 不進行引數型別檢查和轉換,只進行簡單文字替換。

(3)  不利於一些工具對程式的處理。在c++的編譯結果中,所有的巨集定義都已經不存在了,這就會給一些軟體工具(如除錯程式)在源程式與目標程式之間進行交叉定位帶來困難。

鑑於以上因素,c++提供了另外一種解決函式呼叫效率不高的機制:內聯函式。即在函式的定義中,可以在函式返回型別前加上關鍵字inline,其作用是建議編譯程式把該函式的函式體展開到呼叫點,內聯函式形式上屬於函式而又有巨集定義的高效率。 如:

inline  int  max(int a , int b)

使用內聯函式時注意:

(1) 編譯程式對內聯函式的限制。給函式定義加上inline 只是建議編譯程式把該函式當內聯函式來處理,至於編譯程式是否把它當內聯函式處理,這要視具體情況而定。有些函式定義即使加上關鍵字inline,編譯程式也不會把它當內聯函式處理,例如遞迴函式(或函式體內的**太多)。

(2) 內聯函式名具有檔案作用域,即各個原始檔中定義的同名內聯函式屬於不同的函式。在使用同乙個內聯函式的各個原始檔中都要對其定義,所以一般把內聯函式的定義放在某個標頭檔案中,使用該內聯函式的原始檔需要把該標頭檔案包含進來。

(3)預設情況下,編譯程式會把c++類中的成員函式當內聯函式來處理,而在類外部定義的成員函式需要顯示的加上關鍵字inline , 編譯程式才會把它當內聯函式處理。

以上大部分出自《程式設計教程》(用c++語言程式設計)

巨集與內聯函式

建議 1 使用const定義常量而不是 define 2 使用inline內聯函式而不是 define來定義小型函式 第一部分 巨集 為什麼要使用巨集呢?因為函式的呼叫 必須要將程式執行的順序轉移到函式所存放在記憶體中的某個位址,將函式的程式內容執行完後,再返回到轉去執行該函式前的地方。這種轉移操作...

巨集與內聯函式

第一部分 巨集 為什麼要使用巨集呢?因為函式的呼叫必須要將程式執行的順序轉移到函式所存放在記憶體中的某個位址,將函式的程式內容執行完後,再返回到轉去執行該函式前的地方。這種轉移操作要求在轉去執行前要儲存現場並記憶執行的位址,轉回後要恢復現場,並按原來儲存位址繼續執行。因此,函式呼叫要有一定的時間和空...

內聯函式與巨集

當函式被宣告為內聯函式之後,編譯器會將其內聯展開,而不是按通常的函式呼叫機制進行呼叫.內聯函式不是在呼叫時發生控制轉移,而是在編譯時將函式體嵌入在每乙個呼叫處。編譯時,類似巨集替換,使用函式體替換呼叫處的函式名。一般在 中用inline修飾,但是能否形成內聯函式,需要看編譯器對該函式定義的具體處理。...