C++ Primer筆記--1
目錄
- 引用
- 指針
- const 與指針
- 類型說明符auto
- 類型說明符decltype()
C++ Primer-復合類型
復合類型是指基於其他類型定義的類型,其中有這幾種:
- 數組
- 字符串
- struct 結構
- enum 枚舉
- union 共用體
- 指針
- 引用
這裏看看其中的引用和指針。
引用
引用為對象齊了另外一個名字,引用類型引用另外一種類型。通過將聲明符寫成&d
的形式來定義引用類型,其中d
是聲明的變量名。引用不是對象。
#include <iostream> using namespace std; int main() { char ch(65); char * p = &ch;//指針 char &r = ch;//引用 cout << ch << "\n";//輸出A *p = ch+1;//ch++; cout << ch << "\n";//輸出B r = ch+2;//ch+=2; cout << ch << "\n";//輸出D return 0; }
引用的賦值時綁定變量,初始化之後引用就會和其初始綁定對象一直綁定。對引用進行操作其實就是對其綁定對象進行操作。
引用無法解綁,初始化之後不可改變。引用一般只能綁定到對象上,不能與字面值
或者某個表達式的計算結果
綁定在一起。
int &refer = 0;//錯誤,引用類型初始值不能為字面常量
double d = 3.14;
int &refer1 = d;//錯誤,`int`類型的引用不可綁定到`double`類型上
指針
指針也是對其他對象的間接訪問,類似於C裏面的指針。指針與引用不同,其本身是對象,允許對指針進行賦值、拷貝;指針無需在定義時進行賦值。未被初始化的指針是一個不確定的指針。
C++中指針定義方式與C中一致。
引用不是對象,因此無法創建指向引用的指針。
指針的值應該是對象的地址,值有下列四種狀態:
- 指向一個對象
- 指向緊鄰對象所占空間的下一個位置
- 空指針
空指針不指向任何對象。創建一個空指針可以如下幾種方式:
int *p = nullptr;
int *pp = 0;
int *ppp = NULL;
- 無效指針
後三種情況一般都會造成不可估計的後果。
const 與指針
之前C部分的筆記中提到了const
與指針的組合,C++中基本一致。下面看一種情況:
char ch = 'A'; typedef char *pstring; const pstring cstr = &ch; *cstr = 'G';
這種情況下*cstr = ‘G‘
這個賦值合法嗎?有的同學就會認為const pstring cstr = &ch;
的意思就是const char *cstr = &ch;
,因此cstr
是一個指向常量的指針,通過這個指針對對象進行修改是不合法的。但是,我們知道typedef
與宏定義是不一樣的,它不是簡單的文本替換。這裏pstring
其實已經是一種數據類型了,他的類型就是char *
,即字符指針。所以這時候用const
修飾cstr
這個變量,就和const int foo = 0;
一樣,只不過這裏int
換成了pstring
,const
所規定的常量是個指針,所以最終cstr
是一個常量指針,而不是一個指向常量的指針,因此是可以通過cstr
對ch
的值進行修改的。反之,const char *cstr = &ch;
這種寫法就含義不一樣了。這裏const
修飾的基本數據類型是什麽呢?是char
,這裏*
變成了指針的聲明符,所以這樣寫意義就是cstr
是一個指向常量字符的指針。
另外,C++中引入了using
這個關鍵字來達到typdef
的效果。上面typedef char *pstring
可以改寫成using pstring = char *;
。
類型說明符auto
C++中auto
與C中的auto
關鍵字好像很不一樣啊。C++中auto
是讓編譯器分析表達式來確定變量的類型。auto
定義的變量必須進行初始化。
int a = 10;
int b = 10;
auto c = a+b;//這裏沒有直接聲明c的類型,而是通過a,b相加推斷出來c是int。c=20
auto
的使用很靈活:
int a = 10;
int b = 10;
auto c = a+b;
auto *p = &c;//p被自動推斷出為int *。
int &r = a;
auto rr = r;//rr被自動推斷為int,因為r只是a的引用,a的類型才是rr的類型
const auto d = a;//auto推斷出int,那麽d的類型就成了`const int`。
可以在一個auto
語句中同時推斷多個變量的類型,但前提條件是這些變量的類型不會沖突,即都是一個類型的。
auto a = 10; b = 100;//正確,a,b都是int
auto a = 10; b =0.01;//錯誤,a,b不是同一個類型
類型說明符decltype()
auto
是用變量的初始化值的類型推斷變量本身的類型,而decltype()
則是推斷出表達式的類型,但是僅僅返回類型而不使用值:
decltype(f()) foo = x;//推斷出f函數返回值類型,聲明foo為該類型,並用x的值進行初始化。
int a = 10
decltype(p) pp = &a;//p是int *,pp也是
int &g = a;
decltype(g) r = a;//g是一個引用,因此r是int &類型。
decltype(a) e;//a是int,那麽e也是int,可以不進行初始化
// decltype((a)) h;//這種雙括號寫法會導致h的類型被認為是引用,不進行初始化不合法
decltype((a)) h =a;
C++ Primer筆記--1