預設引數,函式過載,引用,行內函數...
目錄
預設引數 (預設引數)
定義:指當函式呼叫中省略了實引數時自動使用的一個值。
例如: void func(int a = 1){...}
呼叫 func() 相當於 func (1);
全預設引數:所有引數都有預設值 。例: void func (int a = 0, int b = 1, int c = 2)
半預設引數:部分引數帶有預設值,必須從右往左依次給出 在呼叫賦值從左-->右
預設引數不能在宣告和定義中同時出現。(最好出現在宣告時)
注: 預設值是常量或者全域性變數
函式過載
定義:是函式一種特殊情況,C++允許在同一作用域中宣告幾個功能類似的同名函式
為什麼C語言不支援過載而C++可以?
在C語言環境下呼叫int型的Add函式:
再呼叫float型的Add函式:
C語言中,編譯器對函式名字的修飾規則:僅在函式名前加"_"。所以當函式過載後,編譯器無法解析它們的不同,所以 C語言不 能過載。
C++環境下執行的結果:
C++函式名修飾規則:
Visual C++的名稱修飾規則 :修飾後名字由“?”開頭
函式名由“@”符號結尾的函式名
後面跟著由“@”結尾的類名和名稱空間(此處未建立類和名稱空間所以沒有)
第一個“A”表示函式呼叫型別為“_cdecl”
接著是函式的返回值型別及兩個引數型別,由“@”結束 // int ---> H ; double ---> N
最後由“Z”結尾
所以,由於命名規則的不同,C語言不能函式過載而C++可以。
引用
概念:引用並不是重新定義一個變數,而是給已存在的變數取別名,對引用的操作與對變數直接操作完全一樣。它會與所引用的變數公用同一塊空間,所以不用再另開闢空間。
功能:
作為函式引數
// 與C語言不同,C++的引用會直接將實參地址當作引數傳遞
void swap(int &A, int &B)
{
int tmp;
A = tmp;
A = B;
B = tmp;
}
從函式中返回左值。
int &Func(int &a)
{
a += 1;
return a;
}
特性:
1. 一個變數可以有多個別名;
2. 一旦引用一個實體,不能再引用其他實體;
3. 引用型別必須和引用實體同一型別;
4. 引用定義必須初始化;
5. 引用在編譯器中是以const指標實現的,所以它與指標佔相同大小的記憶體;
6. 由於引用只能引用一個實體,所以它不能引用一個數組(許多元素的集合),但是可以建立陣列的引用;
常引用
通過宣告定義前加const,使得目標變數不可通過引用修改,增加程式碼安全性,健壯性。
宣告方式:const 型別識別符號 &引用名 = 目標變數名;
引用和指標的不同點:
1. 引用在定義時必須初始化,指標沒有要求;
2. 引用在初始化時引用一個實體後,就不能再引用其他實體,而指標可以在任何時候指向任何一個同一型別實體;
3. 沒有NULL引用,但有NULL指標;
4. 在sizeof中含義不同:引用結果為引用型別的大小,但指標始終是地址空間所佔位元組個數(32位平臺下佔4位元組);
5. 引用自加即引用的實體增加1,指標自加即指標後偏移一個型別大小;
6. 有多級指標,但沒有多級引用;
7. 訪問實體方式不同,指標需要顯示解引用,引用編譯器自己處理;
8. 引用比指標使用起來相對安全。
行內函數
---既保留了巨集的特性,又比較安全
以inline修飾的函式叫做行內函數,編譯時C++編譯器會在呼叫行內函數的地方展
開,沒有函式壓棧的開銷,行內函數提升程式執行的效率,是一個以空間換時間的做法。
但是加上inline不一定會被當作行內函數,若函式中有遞迴,迴圈,函式較長不適用做行內函數。
inline對編譯器只是一個建議。
// 由於巨集定義<不開闢棧空間>:不安全,產生副作用,不能除錯;所以就有了行內函數。
巨集的優缺點:
優點:
1. 增強程式碼的複用性;
2. 提高效能;
缺點:
1. 不方便除錯(預編譯階段進行了替換);
2. 沒有型別檢測;
3. 導致程式碼可讀性差,可維護性差,容易誤用。
C++那些地方可以替換巨集?
巨集函式 ---》 inline
巨集變數 ---》 const
基於範圍的for迴圈
語法: for(auto 迭代的變數 : 迭代的範圍)
規則:
1. for迴圈範圍必須確定:對於陣列,就是陣列的大小;
對於類,提供begin和end的方法
2. 迭代物件實現++和==的操作
指標空值---nullptr
C語言中表示空指標:
int* p1 = NULL; // NULL是一個巨集
// 定義為:字面常量0 或者 無型別指標(void*)的常量
// 考慮到相容性,保留了NULL
int* p2 = 0;
C++11中:
int* p3 = nullptr;指標空值常量
nullptr是有型別的,其型別是nullptr_t,僅僅可以被隱式轉化為指標型別;
注意:
1. 在使用nullptr表示指標空值時,不需要包含標頭檔案,因為nullptr是C++11作為新關鍵字引入;
2. 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所佔位元組數相同;
3. 為提高程式碼健壯性,在後續表示指標空值時建議最好使用nullptr。