複合類型是指基於其他類型定義的類型;一條聲明語句由一個基本數據類型和緊隨其後的一個聲明符列表組成
2.3.1 引用
【使用格式:
int i = 0;
int &a = i;//a 爲對整形對象i 的引用
】
【引用爲對象起了另外一個名字,引用類型引用另外一種類型。
引用並非對象,它只是爲一個已經存在的對象所起的另外一個名字,所以不能定義引用的引用。】
【定義引用時,程序把引用和它的初始值綁定在一起,而不是將初始值拷貝給引用。
一旦初始化完成,引用將和它的初始值對象一直綁定在一起。
因爲無法令引用重新綁定至另一個對象,因此引用必須初始化。】
【定義了一個引用之後,對其進行的所有操作都是在與之綁定的對象上進行的。
所以大多情況下,引用的類型必須和與之綁定的類型嚴格匹配(否則由於不同類型能進行的操作不同,對引用進行的操作可能無法應用於其綁定的對象)。
大多情況下,引用只能綁定在對象上,而不能與字面值或某個表達式的計算結果綁定在一起。】
【使用引用而非直接傳遞參數,可以提高函數的空間性能和時間性能。
引用因爲不創建新的對象,在函數中傳遞參數時要比直接傳遞的性能好很多,尤其是傳遞使用者定義的複雜類的時候。】
2.3.2 指針
【引用與指針的異同:
第一, 指針和引用都實現了對其他對象的間接訪問;
第二,指針本身就是一個對象,允許對指針賦值和拷貝,而且在指針的生命週期內它可以先後指向幾個不同的對象;
第三,指針無須在定義時初始化,而引用必須在定義時初始化。】
【一條定義語句可以定義出不同類型的變量,但都是基於聲明語句開始的基本類型的類型。
定義指針的* 只作用於其後緊跟的一個變量名(實際上int* b 也能定義指針b,但容易產生誤解)。
int a,*b = &a,c;
//上條語句中定義了整形變量a 和c,以及指向整形a 的指針變量b
】
【在聲明語句中指針的類型必須要與其所指向對象的類型所匹配。】
【引用和指針中涉及到的符號的用法及不同意義:
int i = 42;
int &r = i;//& 緊跟類型名,是聲明符列表的一部分,r 是一個引用
int *p = &i;//* 出現在類型名後的聲明符列表中,p 是一個指針;& 出現在表達式中,是一個取地址符
*p = 43;//* 出現在表達式中,是一個解引用符
】
【指針的字面值:nullptr(空指針):
int *p = nullptr;//等價於*p = 0;
int *p = 0;
int *p = NULL;//在頭文件cstdlib 中定義,在新標準下儘量避免使用NULL
】
【把int 直接賦值給指針是錯誤的操作,即使int 變量的值恰好等於0 也不行。
因爲對於程序員,使用指針時相當於使用了基址尋址的方法,而在不知道基址的值時對指針賦具體的值毫無意義。】
【將合法指針(有效指針)用於條件表達式時:
只當指針爲空指針時,條件才爲false。】
【void* 指針是一種特殊的指針類型,可用於存放任意對象的地址。
但不能直接操作void* 指針所指的對象,因爲我們不知道該指針所指對象的類型,更不知道該類型可以進行哪些合法的操作。】
2.3.3 理解複合類型的聲明
【存在指向指針的指針,對指針的引用。
int i = 0;
int *p = &i;//p 是指向整形i 的指針
int **q = &p;//q 是指向指針p 的指針
int *&r = p;//r 是對指針p 的引用
int **&t = q;//t 是對指針q 的引用
不存在引用的引用,也不存在指向引用的指針(引用本身不是對象)。】