C++primer 4.2 指针和const限定符(3)

简介

建议(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对象的指针

  1. 如果指针指向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 指针

  1. const指针,指针本身值不能修改,所以定义时就要初始化
  2. 可以赋值为非const常量。
  3. 因为指向的是非const对象的const指针,所以我们可以通过指针来改变所指对象的值。
int errNumb=0;
const int ic=8int *const curErr=&errNumb;//可以,用非const对象赋值指向int型对象的const指针
int *const curErr=&ic;//不可以用const对象给指向int型对象的const指针赋值

curErr =curErr;//错误,任何企图给const指针赋值的行为都会导致编译时的错误
if(*curErr){
errorHandler();
*curErr=0;// 可以,因为指针指的不是一个const型对象
}

三、指向const对象的const指针

  1. 既不能通过指针来修改所指向的对象的值,也不能修改指针的指向。
  2. 必须初始化;
  3. 初始化的对象必须也是const类型的
const double pi=3.14159;
const double *const pi_ptr=&pi;
//不能修改指针的指向,也不能修改指针指向的对象的值

四、指针和typedef

//下面的例子请问cstr是什么类型

typedef string *pstring;
const pstring cstr;


/*因为const修饰的是pstring的类型,这是一个指针,因此,该声明语句应该是把cstr定义为指向string类型对象的const指针,等价于
*/
string *const cstr;
p112

五、理解复杂的const类型的声明

  1. 阅读const声明语句产生的部分问题,源于const限定符既可以放在类型前也可以放在类型后

    1. string const s1;
    2. 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=&ic;//可以, 定义一个指向const对象的指针,可以用const和非const类型对象初始化

int * const cpi=&ic;//不可以,定义一个指向非const对象的const指针,只能用非const对象进行初始化
const int * const cpic=&ic; //可以

i=ic;//可以用const对象修改非const对象的值,反之则不行
pic=&ic;//可以,修改指针pic的指向,使他指向ic
cpi=pic;//不可以,因为指针cpi是const型指针
pic=cpic;//可以,指针指向的变化,指针pic指向对象ic
cpic=&ic;//不可以,cpic是常量指针
ic=*cpic;//不可以,ic是const常量,不能被赋值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章