C++ Primer 學習筆記_Chapter4 數組和指針–指針

一、什麼是指針?

指針與迭代器一樣,指針提供對其所指對象的間接訪問,指針保存的是另一個對象的地址;

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 = 0int *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指針。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章