【C++ const引用和const指针详解】 (const int *p;) (int const *p;) (int *const p;)三者的区别

一. const指针

int *p;定义了一个普通的指针p
而const指针一般有一下几种:

// 指向常量的指针
1const int *p; // 等价于int const *p;
2int const *p;  

// 常量指针
3int * const p;

// 指向常量的常量指针
4const int * const p;

下面我们来讲一讲它们的区别

1.1 const int *p; 和int const *p;

const int n = 3;
int const n = 3; // 两者等价

const与int谁写前都不影响语义

所以说1和2定义的指针是一样的

const int *p; // 定义了一个
// 等价于int const *p;

这里const 修饰的是整个*p,所以你只要记住*p不能被赋值,也就是不能作为左值

例如:

int q = 5;
int const *p = &q;

// 错误 *p是const,不能作为左值
// *p = 7;

const int q2 = 7;
// 正确 p不是const
p = &q2;

1.2 int *const p;

int *const p;

const 修饰的是p,说明p是不能被赋值的,也就是不能作为左值,它只能永远指向初始化时的内存地址了

而此时整个*p的前面没有const 的修饰。也就是说,*p是变量而不是常量,所以我们可以通过*p来修改它所指内存的值

例如:

int q = 5;
int * const p = &q;

// 正确 *p不是const
*p = 7;

const int q2 = 7;
// 错误 p是const,不能作为左值
// p = &q2;

1.3 const int *const p;

此时*p前有const,而且也有const直接在p前面
所以p的值不能改,*p的值也不能修改

例如:

int q = 5;
const int * const p = &q;

// 错误 *p是const,不能作为左值
// *p = 7;

const int q2 = 7;
// 错误 p是const,不能作为左值
// p = &q2;

1.4 辨析技巧总结

1)如果*p前有const修饰,则不能改的是*p(即不能类似这样*p=50;赋值)
2)如果p前有const修饰(const和p中间没有*),const 是直接写在p前,则p不能被赋值(即不能类似这样p = &a赋值)
3)const与int谁写前都不影响语义

注意:不能被更改或不能被赋值的意思就是,不能作为左值

1.5 指针与const进一步说明

(1)要想存放常量对象的地址,只能使用指向常量的指针const int *p;形式

综合示例:
下面的代码错误的原因是,虽然你把p设为了const,但*p不是const,*p会改变q的值,这与q是个const常量矛盾了
在这里插入图片描述

(2)指针类型一般要与其指向的对象类型一致,但有例外

C++允许令一个指向常量的指针指向一个非常量对象
例如:

int q = 5;
int const *p = &q; // 正确:但是不能通过*p去修改q的值
*p = 3; // 错误
q = 8;  // 正确

引用其实也有这种例外情况
对const的引用可以引用一个并非const的对象

int doinb = 1900;
const int &jingugu = doinb;
doinb += 10; // 正确
jingugu += 10; // 错误

解释:所谓指向常量的指针仅仅要求不能通过该指针去改变对象的值,而没有规定那个对象的值不能通过其他途径改变


二. const引用

2.1 int const &b = a;和const int & b = a;

const引用和const指针略有不同

  • int &const b = a;是非法的
  • 不过int const & b = a;const int & b = a;仍然是等价的
int a = 3;
int const & b = a; 
const int & b = a;  // 等价于int const & b = a;

// int &const b = a;  wrong

int &const b = a;是非法的,因为指针是对象,而引用不是对象,所以指针可以被定义为const,而引用没有这种用法,所以不存在常量引用

2.2 引用的类型一般与所引用对象的类型一致,但有例外

(1)允许一个常量引用绑定非常量对象、字面值、甚至是表达式

int i = 42;
const int &r1 = i; // 正确
const int &r2 = 3; // 正确
const int &r3 = i * 5; // 正确
int &r4 = r1 * 2; // 错误

(2)非常量引用不能绑定表达式或字面值

在这里插入图片描述

2.3 题外话:为什么有时还会听到常量引用呢?

那是因为C++程序员们经常把词组“对const的引用”简称为“常量引用”,你要时刻记住它只是个简称,严格来说,并不存在,因为引用不是一个对象,所以我们没有办法让引用本身恒定不变。
可由于C++语言不允许随意改变引用所绑定的对象,所以从这层意义上可以理解所有的引用是“常量”


参考资料

发布了239 篇原创文章 · 获赞 80 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/104298945
今日推荐