简介
建议(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常量,不能被赋值