參考《C++ Primer第4版》(中文版)
1. C++指針含義:指針保存的是另一個對象的地址。引用類型
*解引用符(獲取所指的對象)&取地址
2. 每個指針都有一個與之關聯的數據類型,且該指針只能指向這一種類型的對象。
注意:string* ps1,ps2; 實際上ps1定義為指針,ps2並非指針,只是一個普通的string對象而已。 string* ps1, *ps2; 這樣才是定義了兩個指針。
3. 指針取值為NULL相當於等於0.未初始化的指針式無效指針(存放一個不確定的地址),程序中避免使用無效指針。所以指針使用前盡量要初始化。
4. void*指針:可以保存任何類型對象的地址。
操作限制:與另一個指針進行比較;
向函數傳遞void*指針或從函數返回void*指針;
給另一個void*指針賦值。
不允許使用void*指針操作它所指的對象。
5. 區分給指針賦值和通過指針進行賦值
a)如果對做操作數進行解引用,則修改的是指針所指對象的值;
例如:string s1(“hello”); string *sp1 = &s1;
string s2(“world”); *sp1 = s2;
此時指針sp1中所存的地址依舊s1的地址,但修改了s1的值此時s1=”wolrd”;
b)如果沒有使用解引用操作,則修改的是指針本身的值。
例如:string s1(“hello”); string *sp1 = &s1;
string s2(“world”); sp1 = &s2;
此時指針sp1中所存的地址由s1的地址變為了s2的地址,s1值不改變。
6. 區分指針和引用
引用總是指向某個對象,定義時必須初始化。而且引用被賦值是修改該引用所關聯的對象的值,並不是使引用和另一個對象關聯。
例如:int &ri = ival; int&ri2 = ival2;
ri = ri2; //此時只是將ival的值修改成了和ival2相同而已。ri依舊是引用的ival
7. 二重指針:指向指針的指針。
int ival = 1024; int *p = &ival; int **pp = &p;
此時p中存的是ival的內存地址,pp中存的是指針p的地址。兩次解引用得到ival的值
例如:**pp == ival; 這是成立的。
以此類推:還有三重指針等,當然不常用了,使用時要小心。
8. 指針與數組
a) C++中使用數組名,自動轉換為指向數組第一個元素的指針。
b) 如果有int arr[5] = {0,1,2,3,4}; int*p = arr;
指針p進行加減操作即改變所指元素,加1為指向下一個元素,減1為指向上一個元素(注意防止越界)。++、-- 操作同理。
c) 兩個指向同一數組的指針可以做減法操作。例如:int *p2 = &arr[4];
則,p2 – p1==4;成立。減法操作結果為ptrdiff_t類型(是signed整型,可以是負數)。
d) 允許指針加減0.兩個空指針相減結果仍為0.
e) 數組的下標運訪問元素時,實際上是對指向數組元素的指針做下標操作。
f) C++允許計算數組或對象的超出末端的地址,但不允許對此地址進行解引用操作。而計算數組超出末端位置之後或數組首地址之前的地址都是不合法的。常用數組末端的下一個元素做“哨兵”。
9. 指針和const限定修飾符
a) const int *p; //p不是const的。可以不初始化p,可以更改p指向的對象;
b) 不能用void*指針保存const對象的地址,必須用const void*指針保存const對象的地址
c) 允許把非const對象的地址賦給指向const對象的指針,但是不能通過p更改指向對象的值:
int a = 3; p = &a;
a=4;//可以 *p = 5;//錯誤
d) const指針:指針一旦初始化不能再更改指向的對象
int c = 8; int*const cp = &c;
cp只能指向c不能再指向別的對象,可以通過cp更改c的值
e) 指向const對象的const指針:既不能修改指針所指對象的值,也不允許指針再指向別的對象:
const int d = 6; constint *const dp = &d;
int c = 9; dp =&c; //錯誤 *dp = 7; //錯誤
f) 注意陷阱:typedefstring *pstring;
const pstring cstr;
cstr的真正類型是:string *const cstr; 而不是const string *cstr;
作者:TskyFree