一、什麼是指針?
指針與迭代器一樣,指針提供對其所指對象的間接訪問,指針保存的是另一個對象的地址;
string s("hello");
string *ps = &s; //ps holds the address of s
二、指針的定義和初始化
1、兩種聲明指針變量的風格
string *ps1;
string* ps2;
理解指針聲明語句時,請從右向左閱讀:
從右向左閱讀pstring變量的定義,可以看到:
string *pstring;
語句把pstring定義爲一個指向string類型對象的指針變量。
2、避免使用未初始化的指針
int *pi; //ok, but dangerous,pi is uninitialized
三、指針初始化和賦值操作的約束
對指針進行初始化和賦值只能使用以下四種類型的值:
1. 0值常量表達式;
2. 類型匹配的對象的地址;
3. 另一對象之後的下一地址;
4. 同類型的另一個有效指針。
四、void* 類型的指針
void* 類型的指針可以保存任何類型對象的地址。
double obj = 3.14;
double *pd = &obj;
void* pv = &obj;
pv = pd;
五、指針操作
1、生成左值的解引用操作
(1)解引用操作符返回指定對象的左值,利用這個功能可修改指針所指對象的值;
(2)修改指針本身的值,使sp指向另一個新的對象;
string s2 = "some new value";
sp = &s2;
2、指針和引用的比較
指針的和引用的相同點:
兩者都可以間接訪問另一個值;
指針和引用的重要區別:
(1)引用一經初始化,就始終指向某個特定對象,所以引用必須在定義時初始化;
(2)賦值行爲的差異:給引用賦值修改的是該引用所關聯的對象的值,而並不是使引用與另一個對象關聯。引用相當於起別名。
3、使用指針訪問數組元素
4、指針和const限定符
【指向const對象的指針】
【const指針】
1)指向const對象的指針
定義方式:
const double *cptr;
這裏cptr是一個指向double類型const對象的指針,const限定了cptr所指向的對象類型,而並非cptr本身。也就是說cptr本身並不是const,所以,cptr在定義時,並不一定需要初始化。
【Warning】:
1、C++語言強制要求指向const對象的指針也必須具有const特性;
2、不能通過cptr修改所指對象的值;
*cptr = 42; //Error
3、把一個const對象的地址賦給一個指向普通的、非const對象的指針也會導致編譯時的錯誤;
const double pi = 3.141592653589793 ;
double *pd = π //Error
const double *cptr = π //OK, cptr is a pointer to const
4、不能使用void*指針保存const對象的地址,而必須使用const void*類型的指針保存const對象的地址;
5、允許把非const對象的地址賦值給指向const對象的指針
double dval = 3.14;
cptr = &dval; //ok, but can not change dval through cptr
但是,我們不能夠保證指向const的指針所指對象的值一定不可修改。
2)const指針
int errNumb = 0;
int *const curErr = &errNumb; //curErr is a constant pointer
從右向左把上述定義讀作“curErr是指向int 型對象的const 指針”
3、指向const對象的const指針
4、指針和typedef
在typedef中使用指針往往會帶來意外的結果。
typedef string *pstring;
const pstring cstr;
請問cstr變量是什麼類型?
很多人都會認爲真正的類型是:
const string *cstr;也就是說,const pstring是一種指針,指向string類型的const對象,
但是:這是錯誤的!!!
錯誤的原因:
將typedef當做文本拓展了。聲明const pstring時,const修飾的是pstring的類型,這是一個指針。因此,該聲明語句應該是把cstr定義爲指向string類型對象的const指針,這個定義等價於:
//cstr is a const pointer to string
string *const cstr;
建議:
理解複雜的const類型的聲明
閱讀const聲明語句產生的部分問題,源於const限定符既可以放在類型前也可以放在類型後:
string const s1;
const string s2; //s1 and s2 both strings that are const
用typedef寫const類型定義時,const限定符加在類型名前面容易引起對所定義的真正類型的誤解:
string s;
typedef string *pstring;
const pstring cstr1 = &s;
pstring const cstr2 = &s;
string *const cstr3 = &s;
把const放在類型pstring之後,然後從右向左閱讀該聲明語句就會非常清楚的知道cstr2是const pstring類型,即指向string對象的const指針。