簡介
建議(remember)
- 指向const對象的指針(const和非const都可以)
1. 可以初始化爲const和非const的對象;
2. 把非const對象的地址賦給指針時,不允許用指針來改變其所指的const的值;
3. 定義指針時不需要初始化
- 指向非const對象const指針(只能非const對象)
1. 指針一直指向某一個對象,指針不能被修改;
2. **定義時必須初始化指針,初始化爲非const的對象,不能初始化爲const對象**;
3. 因爲指向的是非const對象的const指針,所以我們可以通過指針來改變所指對象的值。
4. 所指對象值的變化和指針沒有關係
- 指向const對象的const指針(只能const對象)
1. 既不能通過指針來修改所指向的對象的值,也不能修改指針的指向。
2. 必須初始化;
3. 初始化的對象必須也是const類型的
- 關於const 需要記住的
1. 常量是不能被賦值的,const定義的都是常量,且定義一個const對象必須初始化,無論是const變量還是const指針或是const數組;
2. 如果const定義針對的是指針,那麼那個指針就不能再被賦值;
3. 如果定義的是一個整型或是別的類型對象,那麼該對象初始化後也不能再被賦值
4. const位置的不同修飾的也不同,區別const指針和指向const對象的指針的區別;
5. 前者針對指針,所以指針不能變,並不對其所指的對象有限制,對象的值還是可以變的;
6. 後者修飾的是所指的對象,所以對象的值不能變,但是指針可以
疑問:
p112
=======================================================================================================================================
一、指向const對象的指針
- 如果指針指向const對象,則不允許用指針來改變其所指的const的值,爲了保證這個特性,要求指向const對象的指針也必須具有const特性;
const double * cptr
//cptr是一個指針,是一個指向 double類型const型對象的指針`
//因爲const是對指針所指的對象做出的限定,所以定義時不需要對指針cptr進行初始化
//如果需要的話,允許給cptr重新賦值,使其指向另一個const對象,但不能通過cptr修改其所指對象的值
*cptr=42; //這是錯誤的
//把一個const對象的地址賦給一個普通的、非const對象的指針也會導致編譯出錯
const double pi=3.14;
double *ptr=π //錯誤,因爲ptr不是const類型指針
const double *cptr=π//可以
//允許把非const對象的地址賦給指向const對象的指針
double dval=3.14;
cptr =&dval;//可以,但是不能通過指針來修改dval的值,可以通過別的方法來
//可以修改const指針所指向的的值
dval =3.14159;
*cptr=3.14159; //錯誤,不可以通過指針來修改const對象的值
double *ptr=&dval;
*ptr=2.72;//可以,因爲ptr是一個普通指針,所以dval的值改成了2.72
cout<<*cptr<<endl;//輸出2.72
二、指向非const對象的const 指針
- const指針,指針本身值不能修改,所以定義時就要初始化
- 可以賦值爲非const常量。
- 因爲指向的是非const對象的const指針,所以我們可以通過指針來改變所指對象的值。
int errNumb=0;
const int ic=8;
int *const curErr=&errNumb;//可以,用非const對象賦值指向int型對象的const指針
int *const curErr=⁣//不可以用const對象給指向int型對象的const指針賦值
curErr =curErr;//錯誤,任何企圖給const指針賦值的行爲都會導致編譯時的錯誤
if(*curErr){
errorHandler();
*curErr=0;// 可以,因爲指針指的不是一個const型對象
}
三、指向const對象的const指針
- 既不能通過指針來修改所指向的對象的值,也不能修改指針的指向。
- 必須初始化;
- 初始化的對象必須也是const類型的
const double pi=3.14159;
const double *const pi_ptr=π
//不能修改指針的指向,也不能修改指針指向的對象的值
四、指針和typedef
//下面的例子請問cstr是什麼類型
typedef string *pstring;
const pstring cstr;
/*因爲const修飾的是pstring的類型,這是一個指針,因此,該聲明語句應該是把cstr定義爲指向string類型對象的const指針,等價於
*/
string *const cstr;
p112
五、理解複雜的const類型的聲明
閱讀const聲明語句產生的部分問題,源於const限定符既可以放在類型前也可以放在類型後
- string const s1;
- const string s2;
2.用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指針
*/
六、課後習題
記住:
1. 常量是不能被賦值的,const定義的都是常量;
2. 如果const定義針對的是指針,那麼那個指針就不能再被賦值;
3. 如果定義的是一個整型或是別的類型對象,那麼該對象初始化後也不能再被賦值
4. const位置的不同修飾的也不同,區別const指針和指向const對象的指針的區別;
5. 前者針對指針,所以指針不能變,並不對其所指的對象有限制,對象的值還是可以變的;
6. 後者修飾的是所指的對象,所以對象的值不能變,但是指針可以
7.
//下面這個例子可以驗證自己對概念理解的如何
int i=-1;
const int ic=i; //可以,初始化,用const和非const變量給const變量初始化,但是後面ic的值就不能變了,就是後面const對象不能被賦值了。
const int *pic=⁣//可以, 定義一個指向const對象的指針,可以用const和非const類型對象初始化
int * const cpi=⁣//不可以,定義一個指向非const對象的const指針,只能用非const對象進行初始化
const int * const cpic=⁣ //可以
i=ic;//可以用const對象修改非const對象的值,反之則不行
pic=⁣//可以,修改指針pic的指向,使他指向ic
cpi=pic;//不可以,因爲指針cpi是const型指針
pic=cpic;//可以,指針指向的變化,指針pic指向對象ic
cpic=⁣//不可以,cpic是常量指針
ic=*cpic;//不可以,ic是const常量,不能被賦值