面試之簡答題


帶參數的宏與內聯函數之間的區別

答:宏定義是C語言提供的三種預編譯處理功能的一種。三種分別是文件包含、宏定義、條件編譯。

格式: #define 標識符 字符串 

其中的標識符就是所謂的符號常量,也成爲宏名。宏是在預編譯期間簡單替換(是在預處理完成的),將宏名替換爲字符串,也叫作宏展開。說白了,宏就是簡單的字符串替換。

重要的一點是,對於帶參數的宏,不作任何類型和語法的檢查。

內聯函數:c++支持函數內聯,這是爲了提高程序的效率。但是使用內聯函數要注意以下幾點。

1、含有遞歸調用的函數不能被聲明爲內聯函數。

2、內聯函數增加了代碼的體積,所以內聯函數的代碼應該短小。

3、在一個文件中定義的內聯函數不能在另一個文件中使用,它們通常放在頭文件中共享。內聯函數的定義和聲明要放在同一個文件中。

4、內聯函數體中,不能有循環結構、if語句和switch語句。

5、內聯函數的定義對編譯器而言必須是可見的,以便編譯器能夠在調用點內聯展開該函數的代碼。


關鍵字inline 必須與函數定義體放在一起才能使函數成爲內聯,僅將inline 放在函數聲明前面不起任何作用。

如下風格的函數Foo 不能成爲內聯函數:

<span style="font-size:18px;">inline void Foo(int x, int y); // inline 僅與函數聲明放在一起

void Foo(int x, int y){}</span>

如下風格的函數Foo 則成爲內聯函數:

<span style="font-size:18px;">void Foo(int x, int y);

inline void Foo(int x, int y){} // inline 與函數定義體放在一起</span>

inline 是一種“用於實現的關鍵字”,而不是一種“用於聲明的關鍵字”。

定義在類聲明之中的成員函數將自動地成爲內聯函數

class A

{

    public:

    void Foo(int x, int y) {  } // 自動地成爲內聯函數

}

將成員函數的定義體放在類聲明之中雖然能帶來書寫上的方便,但不是一種良好的編程風格,上例應該改成:

<span style="font-size:18px;">class A
{

    public:
    void Foo(int x, int y);
}
inline void A::Foo(int x, int y){} </span>

帶參數的宏和內聯函數的相同點是都是在程序出現的地方展開,內聯函數不是通過函數調用實現的,是在調用該函數的程序處將它展開,帶參數的宏在預編譯期間展開。


不同點:內聯函數可以在編譯期間完成類型和語法的檢查,而帶參數的宏不具有這樣的功能。另外,帶參數的宏展開時間和內聯函數展開時間是不同的。


對於宏定義注意幾點

1、宏定義允許嵌套。

2、字符串中永遠不能包含宏。

#define NAME "A234"
void main()  
{  
     cout<<"NAME"<<endl;//這裏的NAME不能用定義的宏替換
  
}  

3、宏定義不分配內存,變量定義分配內存。

帶有參數的宏還沒有細講,有時間再說吧。。。。。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章