文章目录
(一)指针和const
const关键字加在定义变量之前。说明定义的变量是一个常变量
int a = 10;
int* p = &a;
//p是一个int类型的指针变量,保存a的地址
*p = 20; //可以通过解引用的方式修改保存地址中的值
const int* p1 = &a;
int const *p2 = &a;
int* const p3 = &a;
const int* const p4 = &a;
分析:
- (常指针)p1、p2 指向a的地址,const修饰的是*p1 和 *p2,所以p1和p2的值可以修改,*p1 和 *p2的值不可修改
- p3 指向a的地址,const修饰的是p3,所以p3的值不可修改,*p3的值可以修改
- p4指向a的地址,从右向左,第一个const修饰p4的值,第二个const修饰p4的值,所以p4和p4的值都不可修改
结论:
(二)能力缩小定律
(1)小试身手
我们对(一)进行小小地修改,看下面那句代码编译错误?
int a = 10;
int* p = &a;
const int* p1 = p;
int const *p2 = p;
int* const p3 = p;
const int* const p4 = p;
分析:
结论:编译通过
(2)小试身手
这次我们在*p的前面加上const,那这次的编译结果呢?
int a = 10;
const int* p = &a;
int* p0 = p;
const int* p1 = p;
int const *p2 = p;
int* const p3 = p;
const int* const p4 = p;
分析:
结论:p0 p3编译不通过,其余可以编译通过
(3)小试身手
再次修改,那麽这次的编译结果呢?
int a = 10;
int* const p = &a;
int* p0 = p;
const int* p1 = p;
int const *p2 = p;
int* const p3 = p;
const int* const p4 = p;
分析:
结论:都可以编译通过
(三)指针+引用
也可以看看这种形式的使用,下面的编译情况呢??
int a = 10;
int *p = &a;
int* p0 = p;
int *&s = p; //true
int &*q = p; //error
分析:主要难度就在后两句上,符号从右向左解释
int *&s = p;
这句意思就是s是指针p的引用,所以可以编译通过
int&* q = p;
这句话没有任何意思,编译错误
(四)指针+引用+const
在看懂上面的所有情况之后,再来看这种形式的使用,想必一定是手到擒来了吧,吧。
int a = 10;
int b = 20;
int* p = &a;
int*& s = p; //s是指针p的引用
const int*& s1 = p; //err (引用就是起别名,所以需要做到能力一致)
int* const &s2 = p; //可以编译通过 此时使用s2 = &b;就会报错(必须是可修改的左值)
int*& const s3 = p; //可以编译通过
结果: