C++複習要點總結之二——函數

來源:互聯網
上載者:User
一 inline內嵌函式

C++為什麼要內嵌函式,什麼是內嵌函式,內嵌函式的價值是什嗎?

我們已經知道了對於一個常量我們可以使用const代替宏定義,例如 const int A=3; #define A 3

那麼對對於一個函數,是否也可以達到這樣宏替換的效果。

請看:

#define MYFUNC(a, b) ((a) < (b) ? (a) :(b)) // 宏替換的表示inline int myfunc(int a, int b) //函數表示{ returna < b ? a : b;}

這就是內嵌函式。注意一下說明

說明1:

必須inline int myfunc(int a, int b)和函數體的實現,寫在一塊

說明2

C++編譯器可以將一個函數進行內聯編譯

被C++編譯器內聯編譯的函數叫做內嵌函式

內嵌函式在最終產生的程式碼中是沒有定義的

C++編譯器直接將函數體插入在函數調用的地方

內嵌函式沒有普通函數調用時的額外開銷(壓棧,跳轉,返回)——存在價值

說明3:C++編譯器不一定準許函數的內聯請求!

說明4

內嵌函式是一種特殊的函數,具有普通函數的特徵(參數檢查,傳回型別等)

內嵌函式是對編譯器的一種請求,因此編譯器可能拒絕這種請求

內嵌函式由 編譯器處理,直接將編譯後的函數體插入調用的地方

宏程式碼片段 由前置處理器處理, 進行簡單的文本替換,沒有任何編譯過程

說明5:

現代C++編譯器能夠進行編譯最佳化,因此一些函數即使沒有inline聲明,也可能被編譯器內聯編譯

另外,一些現代C++編譯器提供了擴充文法,能夠對函數進行強制內聯

如:g++中的__attribute__((always_inline))屬性

說明6:

C++中內聯編譯的限制:

不能存在任何形式的迴圈語句

不能存在過多的條件判斷語句

函數體不能過於龐大

不能對函數進行取址操作

函數內聯聲明必須在調用語句之前

編譯器對於內嵌函式的限制並不是絕對的,內嵌函式相對於普通函數的優勢只是省去了函數調用時壓棧,跳轉和返回的開銷。

因此,當函數體的執行開銷遠大於壓棧,跳轉和返回所用的開銷時,那麼內聯將無意義。

結論:

1)內嵌函式在編譯時間直接將函數體插入函數調用的地方

2)inline只是一種請求,編譯器不一定允許這種請求

3)內嵌函式省去了普通函數調用時壓棧,跳轉和返回的開銷

二 函數預設參數

C++中可以在函式宣告時為參數提供一個預設值,(需要按照我提供你的值來調用我)

當函數調用時沒有指定這個參數的值,編譯器會自動用預設值代替

void myPrint(int x = 3){printf("x:%d", x);}

函數預設參數的規則

只有參數列表後面部分的參數才可以提供預設參數值

一旦在一個函數調用中開始使用預設參數值,那麼這個參數後的所有參數都必須使用預設參數值

void printAB(int x = 3){printf("x:%d\n",x);}

在預設參數規則,如果預設參數出現,那麼右邊的都必須有預設參數

void printABC(int a, int b, int x = 3, inty=4, int z = 5){printf("x:%d\n",x);}int main62(int argc, char *argv[]){printAB(2);printAB();system("pause");return0;}

三. 函數佔位參數(先佔個坑)

佔位參數只有參數型別宣告,而沒有參數名聲明

一般情況下,在函數體內部無法使用佔位參數

int func(int a, int b, int ) {returna + b;}int main01(){//func(1, 2); //可以嗎?錯誤printf("func(1,2, 3) = %d\n", func(1, 2, 3));getchar(); return0;}

四. 預設參數和佔位參數(結合)

可以將佔位參數與預設參數結合起來使用。 意義: 為以後程式的擴充留下線索 。 相容C語言程式中可能出現的不規範寫法

int func2(int a, int b, int = 0){return a + b;}void main(){//如果預設參數和佔位參數在一起,都能調用起來func2(1,2);func2(1,2, 3);system("pause");}

結論://如果預設參數和佔位參數在一起,都能調用起來

五.函數重載(重點)

1 )函數重載概念

函數重載(FunctionOverload)

用同一個函數名定義不同的函數

當函數名和不同的參數搭配時函數的含義不同



2 )函數重載的判斷標準

函數重載至少滿足下面的一個條件:

參數個數不同

參數類型不同

參數順序不同

3 )函數傳回值不是函數重載的判斷標準

4)編譯器調用重載函數的準則

將所有同名函數作為候選者

嘗試尋找可行的候選函數

精確匹配實參

通過預設參數能夠匹配實參

通過預設類型轉換匹配實參

匹配失敗

最終尋找到的可行候選函數不唯一,則出現二義性,編譯失敗。

無法匹配所有候選者,函數未定義,編譯失敗。

5)函數重載的注意事項

重載函數在本質上是相互獨立的不同函數(靜態鏈編)

重載函數的函數類型是不同的

函數傳回值不能作為函數重載的依據

函數重載是由函數名和參數列表決定的。

六. 函數重載與函數指標的結合

函數重載與函數指標

當使用重載函數名對函數指標進行賦值時

根據重載規則挑選與函數指標參數列表一致的候選者

嚴格匹配候選者的函數類型與函數指標的函數類型

//函數指標 基礎的文法

//1聲明一個函數類型

typedef void (myTypeFunc)(int a,int b) ; //int

//myTypeFunc *myfuncp = NULL; //定義一個函數指標 這個指標指向函數的入口地址

//聲明一個函數指標類型

typedef void (*myPTypeFunc)(int a,int b) ; //聲明了一個指標的資料類型

//myPTypeFunc fp = NULL; //通過 函數指標類型 定義了 一個函數指標 ,

//定義一個函數指標 變數

void (*myVarPFunc)(int a, int b);

//

待補充!

以上就是C++複習要點總結之二——函數的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.