2019/5/13
個人說明:這是我第一次寫博客文章,主要是試寫,寫的不好請諒解。
初學C++
下面是關於函數部分的學習
- 內聯函數
- 默認參數列表
- 缺省參數列表
- 啞元函數
- 內聯函數
函數前面加上inline 關鍵字
1.內聯函數調用原理
編譯過程的最終產品是可執行程序--由一組機器語言指令組成。運行程序時,操作系統將這些指令載入計算機內存中,因此每條指令都有特定的內存地址。計算機隨后將逐步執行這些指令。有時(如有循環和分支語句時),將跳過一些指令,向前或向后跳到特定地址。常規函數調用也使程序跳到另一個地址(函數的地址),並在函數結束時返回。下面更詳細地介紹這一過程的典型實現。執行到函數調用指令時,程序將在函數調用后立即存儲該指令的內存地址,並將函數參數復制到堆棧(為此保留的內存塊),跳到標記函數起點的內存單元,執行函數代碼(也許還需將返回值放入寄存器中),然后跳回到地址被保存的指令處(這與閱讀文章時停下來看腳注,並在閱讀完腳注后返回到以前閱讀的地方類似)。來回跳躍並記錄跳躍位置意味着以前使用函數時,需要一定的開銷
1 寫法如下: 2 3 inline int plus(int a,int b) 4 { 5 6 return a+b; 7 8 }
下面這個宏定義和內聯函數的區別是看別人寫的博客的:
1.內聯函數與宏定義的區別
C語言使用預處理器語句#define來提供宏。如下例所示:
#define SQUARE(X) X*X
宏定義時通過文本替換開實現的--X是參數的符號標記。
a = square(5.0);->a=5.0*5.0;
b = square(4.5+7.5);->b=4.5+7.5*4.5+7.5
d = square(c++);->d=c++*c++
可以看出,對於b,需要使用括號才能正常運算。
#define SQUARE(X) ((X)*(X))
對於c,卻仍遞增了兩次。
因此,宏定義和內聯函數存在本質的區別,轉換的時候應考慮是否轉換后功能是否正常。
什么時候使用內聯函數呢?
說簡單點,就是那種操作數量非常少的,而又封裝成為函數的函數前使用。我把它理解為殺雞焉用牛刀。就是說我函數內部的操作本來就是非常快的,而我調用函數這個步驟會耗費一點時間,比如說,我寫了100個函數,或者10000個函數,在這之中要尋找和調用就會耗費一點點時間,為了最求速度,使用inline
如果執行函數代碼的時間比處理函數調用機制的時間長,則節省的時間占比很小。若代碼執行時間很短,則內聯函數就可以節省函數調用的時間。
2.默認參數列表:
1 int info(int a=10,int b=20,int c=30) 2 { 3 return a+b+c; 4 }
對於一個函數,如果我調用的時候沒有創參,就傳入默認參數列表里的參數
注意:這里的參數是從左到右進行匹配,並且每一個參數都要賦值,如果缺省,情況在下面我會寫到。
更多代碼示例:
1 void foo(char a='b',int b=2,const char* c="xY") 2 { 3 std::cout<<a<<","<<b<<","<< c<<endl; 4 } 5 6 /* 7 8 注意這里的參數必須寫滿 9 10 */
3.缺省參數列表
為函數指定默認值,參數從左往右匹配,因此,缺省參數必須從有開始設置
示例代碼:
1 void bar(char a,int b,const char*c="XY") 2 { 3 cout<<a<<","<<b<<","<<c<<endl; 4 } 5 6 /* 7 8 你的參數如果缺省,從前面開始缺,后面的默認參數要連在一起 9 10 11 */
下面是會報錯的代碼
void bar(char a='b',int b,const char*c) { cout<<a<<","<<b<<","<<c<<endl; } /* 記憶與理解: 由於參數是從左邊到右邊進行匹配的。看下面,調用bar(3,"4"),這樣 3就賦值給 字符a, 中間的b,和 c怎么分配? 因此,規定,默認參數從右邊往左邊寫 */ int main(void) { bar(3,"4"); }
4.啞元函數
示例代碼如下:
void func(int,int b,int) { cout<<b<<endl; } int main(void) { func(1,2,3); //傳參一個都不能少,必須和參數申明的個數一樣 }
啞元函數的意義:
為了兼容老版本:
舉例:假如我寫了一大堆的func 類似的函數 比如 聲明時是 func(int a,int b,int c), 目的是返回 a+b+c
但是后來我返回了,我只有返回 b,返回值只和b 有關,這樣我可以在函數的定義那里改動,改為 func(int b),
但是這樣 我在 main函數里面,凡是調用了 func(a,b,c),的函數,我也要改成 func(b)。
這樣是不是很麻煩? 啞元函數的話就不用在 main 函數里修改了,直接把聲明的 法a,c 全都刪去,只需修改定義函數的那以塊地方就行了。
本人學生,第一次寫博客,可能解釋的不夠專業,或者說的不到位,歡迎各位指出我的錯誤。