天天看點

C++ Primer 學習筆記_Chapter4 數組和指針–指針一、什麼是指針?二、指針的定義和初始化三、指針初始化和指派操作的限制四、void* 類型的指針五、指針操作

一、什麼是指針?

指針與疊代器一樣,指針提供對其所指對象的間接通路,指針儲存的是另一個對象的位址;

string s("hello");
string *ps = &s;             //ps holds the address of s
           

二、指針的定義和初始化

1、兩種聲明指針變量的風格

string *ps1;
string* ps2;
           

了解指針聲明語句時,請從右向左閱讀:

從右向左閱讀pstring變量的定義,可以看到:

string *pstring;
           

語句把pstring定義為一個指向string類型對象的指針變量。

2、避免使用未初始化的指針

三、指針初始化和指派操作的限制

對指針進行初始化和指派隻能使用以下四種類型的值:

1. 0值常量表達式;

2. 類型比對的對象的位址;

3. 另一對象之後的下一位址;

4. 同類型的另一個有效指針。

四、void* 類型的指針

void* 類型的指針可以儲存任何類型對象的位址。

double obj = ;
    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修改所指對象的值;

3、把一個const對象的位址賦給一個指向普通的、非const對象的指針也會導緻編譯時的錯誤;

const double pi =  ;
double *pd = π //Error
const double *cptr = π //OK, cptr is a pointer to const
           

4、不能使用void*指針儲存const對象的位址,而必須使用const void*類型的指針儲存const對象的位址;

5、允許把非const對象的位址指派給指向const對象的指針

double dval = ;
    cptr = &dval;    //ok, but can not change dval through cptr
           

但是,我們不能夠保證指向const的指針所指對象的值一定不可修改。

2)const指針

int errNumb = ;
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指針。

繼續閱讀