国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C > 正文

C語言中的內聯函數(inline)與宏定義(#define)詳細解析

2020-01-26 15:50:52
字體:
來源:轉載
供稿:網友
先簡明扼要,說下關鍵:
1、
內聯函數在可讀性方面與函數是相同的,而在編譯時是將函數直接嵌入調用程序的主體,省去了調用/返回指令,這樣在運行時速度更快。

2、內聯函數可以調試,而宏定義是不可以調試的。
內聯函數與宏本質上是兩個不同的概念如果程序編寫者對于既要求快速,又要求可讀的情況下,則應該將函數冠以inline。下面詳細介紹一下探討一下內聯函數與宏定義。

一、內聯函數是什么?
內聯函數是代碼被插入到調用者代碼處的函數。如同 #define 宏(但并不等同,原因見下文),內聯函數通過避免被調用的開銷來提高執行效率,尤其是它能夠通過調用(“過程化集成”)被編譯器優化。

二、 內聯函數是如何在安全和速度上取得折衷?
在 C 中,你可以通過在結構中設置一個 void* 來得到“封裝的結構”,在這種情況下,指向實際數據的 void* 指針對于結構的用戶來說是未知的。因此結構的用戶不知道如何解釋void*指針所指內容,但是存取函數可以將 void* 轉換成適當的隱含類型。這樣給出了封裝的一種形式。

不幸的是這樣做喪失了類型安全,并且也將繁瑣的對結構中的每個域的訪問強加于函數調用。(如果你允許直接存取結構的域,那么對任何能直接存取的人來說,了解如何解釋 void* 指針所指內容就是必要的了;這樣將使改變底層數據結構變的困難)。

雖然函數調用開銷是很小的,但它會被累積。C++類允許函數調用以內聯展開。這樣讓你在得到封裝的安全性時,同時得到直接存取的速度。此外,內聯函數的參數類型由編譯器檢查,這是對 C 的 #define 宏的一個改進。

 
三、為什么我應該用內聯函數?而不是原來清晰的 #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() 被調用一次
}

和宏不同的,還有內聯函數的參數類型被檢查,并且被正確地進行必要的轉換。宏定義復雜函數是有害的;非萬不得已不要用。

四、如何告訴編譯器使非成員函數成為內聯函數?
聲明內聯函數看上去和普通函數非常相似:
void f(int i, char c);
當你定義一個內聯函數時,在函數定義前加上 inline 關鍵字,并且將定義放入頭文件:inlinevoid f(int i, char c){   // ...}
注意:將函數的定義({...}之間的部分)放在頭文件中是強制的,除非該函數僅僅被單個 .cpp 文件使用。尤其是,如果你將內聯函數的定義放在 .cpp 文件中并且在其他 .cpp文件中調用它,連接器將給出 “unresolved external” 錯誤。

五、如何告訴編譯器使一個成員函數成為內聯函數?
聲明內聯成員函數看上去和普通函數非常類似:
class Fred {public:  
void f(int i, char c);};
但是當你定義內聯成員函數時,在成員函數定義前加上 inline 關鍵字,并且將定義放入頭文件中:inlinevoid Fred::f(int i, char c){   // ...}通常將函數的定義({...}之間的部分)放在頭文件中是強制的。如果你將內聯函數的定義放在 .cpp 文件中并且在其他 .cpp 文件中調用它,連接器將給出“unresolved external”錯誤。

六、 有其它方法告訴編譯器使成員函數成為內聯嗎?
有:在類體內定義成員函數:class Fred {public:   void f(int i, char c)     {       // ...     }};盡管這對于寫類的人來說很容易,但由于它將類是“什么”(what)和類“如何”(how)工作混在一起.小結總之,在嵌入式C(或C++)編程里面,懂得使用內聯函數(inline)與宏定義(#define),并使用好它們,對我們是大有裨益的。(注:本文部分內容來源于網絡整理,上述探討屬于個人意見,僅供參考。錯誤之處也是難免!)
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 龙门县| 德保县| 汉沽区| 洛扎县| 彰化县| 伊宁市| 广汉市| 福安市| 加查县| 东光县| 武川县| 望谟县| 西林县| 凭祥市| 尉氏县| 黑河市| 砀山县| 峨边| 内黄县| 延寿县| 石屏县| 巫溪县| 朝阳区| 隆回县| 石景山区| 吉林省| 永丰县| 腾冲县| 武安市| 滦南县| 杂多县| 道真| 宝丰县| 枣强县| 襄垣县| 上犹县| 腾冲县| 丹棱县| 连南| 宝坻区| 延川县|