《C++ Primer plus》学习记录,const和指针的爱恨情仇

在用const时,我们往往不想某个东西被修改

比如int a,我们想让a这个变量不被改变,就加上const,变成const int a;此时a就从变量变成了常量

代表以后的操作中a的值不能被改变

但const不仅能修饰基本数据类型,还能修饰指针,

const是能随便加吗?加在哪又会有什么影响呢?来,跟我走

先来看基础的不含const的操作

int a=39;
int *pt=&a;

定义一个变量a,值为39;

定义一个指针pt,指向一个int值所在的地址,顺便把a的地址赋给pt;

修改a的值,不会报错;修改pt的值(即pt指向的地址)也不会报错;

理所当然,大家应该都能理解,

霸特!如果加上const,情况会怎样呢,

加上const,总共会有三种情况,

第一种(不行,会报错)

const int a=39;
int *pt=&a;

为什么会报错呢,大家想一想,

a此时是常量,值不能变,地址不变,a地址是在编译时由操作系统的内存分配的,加不加const都不变

但pt可以变,pt可以指向任何int类型的地址,确实,假如代码为

const int a=39;
int *pt=&a;
pt=pt+1;

是没毛病的,但有个问题,没毛病归没毛病,那你pt的存在无意义啊,你创建出来是为了和a发生一些联动,你指向其他地方干啥?没错误但没有用

好,现在我想发生一些联动,

我想让pt修改a的值,比如

const int a=39;
int *pt=&a;
*pt=20;

pt指向的是a的地址,*pt代表那个地址里存放的值,

我们的a是const常量,不让改,你*pt=20给我改了是算什么事,这就是原则上的错误

所以我认为,将const的基本数据类型地址赋给一个常规指针(即不加const的指针)编译器会报错是因为以上两种原因,纯个人理解

第二种(不报错)

int a=39;
const int *pt=&a;

来看看为啥const换了个地方没事,编译器不报错

创建了个变量a,值能变,地址在运行时由操作系统分配,固定不变

然后定义了个pt指针,这行代码可不是说pt指的是一个const int 类型的地址,

而是代表不能用pt这个指针去修改它所指向的地址的值,但是pt所指向的地址可以变

即*pt不能变,但pt可以变

*pt+=1;//错误的,不能这么做
pt+=1;//正确,但为什么要这么做呢,改变地址干嘛呢,一般没有这个操作,虽然正确,但只是演示一下

还有一点,刚刚说过,*pt不能变,但有趣的是,变量a的值可以变,

age=20;//没问题

直接改变a的值没问题,但通过pt改就会错误;

很微妙,pt的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对pt而言,这个值是常量,

例如,pt指向age,而age不是const.可以直接通过age变量来修改age的值,但不能使用pt指针来修改它

*pt=20//错误,不行
age=20//可以,没毛病

第二种情况下的两行代码,第一行改了没问题,符合逻辑,第二行无论是改值还是改地址都说不过去,但至少相比第一种情况来说能改对吧,第一种情况怎么改都说不过去,所以

这可能是C++让第一种情况报错,第二种情况不会报错的原因之一吧(这是我的个人理解)

第三种(不报错)

const int a=39;
const int *pt=&a;

 这种没什么好说的,都是常量,非常好理解,都不让改

这上面都是指针指向基本数据类型的情况

如果现在将指针指向指针,则情况将更复杂

假如涉及一级间接关系,将非const指针指向const指针是可以的,例如

int age=39;
int *pd=&age;
const int *pt=pd;

 然而进入两级间接关系时,与一级间接关系一样将const和非const指针混合的指针赋值方式将不再安全,如果允许这样做,则会有以下闹剧

const int **p2;
int *p1;
const int n=13;

pp2=&p1;//不允许,但假定可以
*pp2=&n;//允许,pp2和n都是const,但这一操作使p1指向了n;
*p1=10;//没问题,但这一步改变了n,但n是const的


综上,如果数据类型本身并不是指针,

则可以将const数据非const数据的地址赋给指向const的指针

非const的指针只能被非const数据的地址赋值

讲了这么多,有没有发现很混乱,

所以,尽可能使用const,出现不安全的概率就会小很多

可以避免由于无意间修改数据而导致的编程错误

大家都知道函数中经常会有参数传入。

函数参数中如果有指针类型的参数,条件允许的话,尽可能声明为指向常量数据的指针(即尽可能使用const)

因为使用const使得函数能够处理const和非const实参,不然只能接收非const实参,很难受

最后再和大家讲一点const的微妙之处

来看三段代码

1

int age=20;
const int *pt=&age;

2

int age=20;
int *const pt=&age;

 3

int age=20;
const int*const pt=&age;

有没有一脸懵逼呢

别慌,follow me

第一种,

这个位置的const只能防止修改pt指向的值,即20这个值,但不能防止pt的值被改

int aaage=80;
pt=&aaage;//没问题
*pt+=1;//不行,错误

第二种

这个位置的const只能防止修改pt的值,但不能防止pt所指向的值不被修改,和第一种反过来

*pt+=1//可以,没问题;
int qqq=23;
pt=&qqq;//不行,错误

第三种无需多言,就是

pt指向的值不能被改,pt本身也不能被改

哈哈哈这是我个人学习c++时遇到的一些让我头疼的一些点,理解后用自己语言重新说一遍

如果对你有帮助,点个赞关个注,谢谢啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangdaliangmvp

如果有帮助,请喝瓶水吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值