程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C說話中的內聯函數(inline)與宏界說(#define)具體解析

C說話中的內聯函數(inline)與宏界說(#define)具體解析

編輯:關於C++

C說話中的內聯函數(inline)與宏界說(#define)具體解析。本站提示廣大學習愛好者:(C說話中的內聯函數(inline)與宏界說(#define)具體解析)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話中的內聯函數(inline)與宏界說(#define)具體解析正文


先長篇大論,說下症結:
1、內聯函數在可讀性方面與函數是雷同的,而在編譯時是將函數直接嵌入挪用法式的主體,省去了挪用/前往指令,如許在運轉時速度更快。

2、內聯函數可以調試,而宏界說是弗成以調試的。
內聯函數與宏實質上是兩個分歧的概念假如法式編寫者關於既請求疾速,又請求可讀的情形下,則應當將函數冠以inline。上面具體引見一下商量一下內聯函數與宏界說。

1、內聯函數是甚麼?
內聯函數是代碼被拔出到挪用者代碼處的函數。好像 #define 宏(但其實不同等,緣由見下文),內聯函數經由過程防止被挪用的開支來進步履行效力,特別是它可以或許經由過程挪用(“進程化集成”)被編譯器優化。

2、 內聯函數是若何在平安和速度上獲得調和?
在 C 中,你可以經由過程在構造中設置一個 void* 來獲得“封裝的構造”,在這類情形下,指向現實數據的 void* 指針關於構造的用戶來講是未知的。是以構造的用戶不曉得若何說明void*指針所指內容,然則存取函數可以將 void* 轉換成恰當的隱含類型。如許給出了封裝的一種情勢。

不幸的是如許做損失了類型平安,而且也將繁瑣的對構造中的每一個域的拜訪強加於函數挪用。(假如你許可直接存取構造的域,那末對任何能直接存取的人來講,懂得若何說明 void* 指針所指內容就是需要的了;如許將使轉變底層數據構造變的艱苦)。

固然函數挪用開支是很小的,但它會被積累。C++類許可函數挪用之內聯睜開。如許讓你在獲得封裝的平安性時,同時獲得直接存取的速度。另外,內聯函數的參數類型由編譯器檢討,這是對 C 的 #define 宏的一個改良。

 
3、為何我應當用內聯函數?而不是本來清楚的 #define 宏? 
由於#define宏界說函數是在四周是無害的:
和 #define 宏分歧的是,內聯函數老是對參數只准確地停止一次求值,從而防止了那申明狼籍的宏毛病。換句話說,挪用內聯函數和挪用正軌函數是等價的,差異僅僅是更快:

// 前往 i 的相對值的宏
#define unsafe(i) \
         ( (i) >= 0 ? (i) : -(i) )

// 前往 i 的相對值的內聯函數
inline
int safe(int i)
{
   return i >= 0 ? i : -i;
}

int f();

void userCode(int x)
{
   int ans;

   ans = unsafe(x++);   // 毛病!x 被增長兩次
   ans = unsafe(f());   // 風險!f()被挪用兩次

   ans = safe(x++);     // 准確! x 被增長一次
   ans = safe(f());     // 准確! f() 被挪用一次
}

和宏分歧的,還有內聯函數的參數類型被檢討,而且被准確地停止需要的轉換。宏界說龐雜函數是無害的;非萬不得已不要用。

4、若何告知編譯器使非成員函數成為內聯函數?
聲明內聯函數看上去和通俗函數異常類似:
void f(int i, char c);
當你界說一個內聯函數時,在函數界說前加上 inline 症結字,而且將界說放入頭文件:inlinevoid f(int i, char c){   // ...}
留意:將函數的界說({...}之間的部門)放在頭文件中是強迫的,除非該函數僅僅被單個 .cpp 文件應用。特別是,假如你將內聯函數的界說放在 .cpp 文件中而且在其他 .cpp文件中挪用它,銜接器將給出 “unresolved external” 毛病。

5、若何告知編譯器使一個成員函數成為內聯函數?
聲明內聯成員函數看上去和通俗函數異常相似:
class Fred {public:  
void f(int i, char c);};
然則當你界說內聯成員函數時,在成員函數界說前加上 inline 症結字,而且將界說放入頭文件中:inlinevoid Fred::f(int i, char c){   // ...}平日將函數的界說({...}之間的部門)放在頭文件中是強迫的。假如你將內聯函數的界說放在 .cpp 文件中而且在其他 .cpp 文件中挪用它,銜接器將給出“unresolved external”毛病。

6、 有其它辦法告知編譯器使成員函數成為內聯嗎?
有:在類體內界說成員函數:class Fred {public:   void f(int i, char c)     {       // ...     }};雖然這關於寫類的人來講很輕易,但因為它將類是“甚麼”(what)和類“若何”(how)任務混在一路.小結總之,在嵌入式C(或C++)編程外面,理解應用內聯函數(inline)與宏界說(#define),並應用好它們,對我們是年夜有裨益的。(注:本文部門內容起源於收集整頓,上述商量屬於小我看法,僅供參考。毛病的地方也是不免!)
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved