522-C++入门(const与一二级指针的结合应用)

const的初步认识

const怎么理解?
const修饰的变量不能够再作为左值!!!
初始化完成后,值不能被修改!!!
在这里插入图片描述
图示b=30;语句错误。因为const修饰b的值为20,之后,b的值就不能被修改了!

C和C++中const的区别是什么?

我们在C文件中使用const
在C语言,把const修饰的量和普通的量都是变量只是const修饰的变量不能作为左值。
在这里插入图片描述
在C语言中,const修饰的量可以不初始化,但是就没有机会再给它合法的值了,因为不能作为左值
在这里插入图片描述

下面这个数组写法是错误的,因为a不是常量,是常变量,所以它不能作为常量/常量表达式来使用。
在这里插入图片描述
在这里插入图片描述
我们把a的类型强转一下:
在这里插入图片描述
指针p指向的是a的内存,const只是语法上保证修饰的量a不能作为左值,但是内存是可以修改的,我们通过指针就可以修改了。
我们也可以通过插入汇编指令去修改a的内存。
在这里插入图片描述
a在ebp-4的位置,给ebp-4写个东西,a的值就变了。
在这里插入图片描述
我们看到,a的内存的值已经被改为30了。
因为在C语言中,a是常变量!!!

我们现在来去看看C++中的const
在C++中,对于const修饰的量是必须要进行初始化的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为是常量,所以可以作为数组的下标哦!

我们把a进行强转看看:
在这里插入图片描述
在这里插入图片描述
可以发现,打印出来的值和在C文件中打印出来的值不一样。

因为对const的编译方式不同,在C中,const就是当作一个变量来编译生成指令的。
但是在C++中,所有出现const常量名字的地方,都被常量的初始化值给替换了!!!

在C++中,相当于是处理成:
在这里插入图片描述
是用20在定义数组的长度。
在这里插入图片描述
*p把a的内存的值改为30了,但是编译器在编译时是把常量a都用20替换了和a的内存就没有关系了。所以,const修饰必须初始化,不然拿谁替换啊???

我们再来看:
在这里插入图片描述
用变量初始化a,但是变量的值是多少只有在运行的时候才知道,所以我们可以认为,a的地方都用变量b来替换了。
在这里插入图片描述
在这里插入图片描述
此时的a已经相当于退化变成C语言中的常变量了。不能定义数组了,也不能替换了。

const与一级指针的结合应用

我们以后给空指针都是用nullptr。因为在C++中,NULL是空指针或者0值。
const修饰的量 叫常量

和普通变量的区别是什么? C++有两点区别?
1.编译方式不同 2.不能作为左值了

C++中const修饰的量常出现的错误是:
1.常量不能再作为左值 =》不能直接修改常量的值
2.不能把常量的地址泄露给一个普通的指针或者普通的引用变量 =》不可以间接修改常量的值
这2点是C++编译器可以检测出来报错的。

我们看下面代码:
在这里插入图片描述
编译通不过。
在这里插入图片描述
在这里插入图片描述
那怎么转换呢?

const和一级指针的结合:有4种情况
在这里插入图片描述

C++的语言规范:const修饰的是离它最近的类型

const int *p = &a;

const修饰的就是int了,因为int本身就可以组成一个类型。
但是我们关心的是const修饰的是什么表达式。什么表达式不能再被赋值了。
我们把修饰的类型去掉,就是const修饰的表达式了:*p
*p就不能被赋值了。
*p被const修饰了,const修饰了指针p的指向,指向的东西不能被赋值了。

p=&b

但是指针本身可以被赋值,因为p本身没有被const修饰。
p可以任意指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值。

int const* p;

const修饰的是离它最近的类型,但是*不是类型哦,不能用 * 定义变量所以修饰的还是int。

int *const p = &a; 

这个const修饰的是int *了,因为 * 自己不能作为类型,所以再往前走,就是int *了
去掉const修饰的类型,就是const修饰的表达式,就是p本身了,p本身是常量,不能被修改,但是 *p没有被const修饰,可以修改。
这个指针p现在是常量,不能再指向其它内存,但是可以通过指针解引用修改指向的内存的值

const int *const p = &a;

前面的const修饰的类型是int,所以const修饰的表达式是*p,所以 *p不能被赋值。
后面的 const修饰的类型是int *,所以修饰的表达式是p,所以p不能被赋值。

在这里插入图片描述
这样*p就不能被解引用了。

下面几种写法都可以指向a:
在这里插入图片描述
我们看这个是什么情况?
在这里插入图片描述
我们先来看下面:
在这里插入图片描述
在这里插入图片描述
const如果右边没有指针*的话,const是不参与类型的!!!
const只用来表示q2是常量
在这里插入图片描述

总结const和指针的类型转换公式:
左值         =   右值 
int*        =    const int*    是错误的!
const int*  =    int*          是可以的!

在这里插入图片描述

在这里插入图片描述
Int *q=p是错误的。const int * 不能赋值给int *
在这里插入图片描述
因为 const右边有 *了
在这里插入图片描述

const与二级指针的结合应用

在这里插入图片描述

左边的类型是const int**,右边的类型是int **

这个类型转换是正确还是错误的???
我们看下面示意图:
在这里插入图片描述
我们现在看这个二级指针q,它的表达式组成就这3种:
q(表示本身的值)
*q(表示它所指向的一级指针p的值)
**q(表示它所指向的一级指针p指向的变量a的值)

const和二级指针的结合:(有3种情况)

在这里插入图片描述
第一种,const修饰的是int类型,所以**q不能被赋值,但是* q可以被修改赋值,q本身也可以被赋值。
第二种,const修饰的是int * 类型,所以 * q不能被赋值,但是q和 **q可以被赋值。
第三种,const修饰的是int * * 类型,所以q不能被赋值,但是*q和 **q可以被赋值。

总结const和指针的类型转换公式:
左值    =   右值 
int*    =    const int*    是错误的!
const int*  =   int*       是可以的!

int**  =  const int**        是错误的!
const int**  =  int**        是错误的!

int**  =  int*const*(这个const是和一级指针的结合,后面是1个*) 是错误的!
==》* =const * 所以是错误的!!!

int*const*  =  int**     是可以的!(*转成const*是可以的)
const* = * 是可以的

我们来分析看看下面这个代码,p和*q都是访问一级指针的内存。
在这里插入图片描述
我们看,现在,p是普通的指针,*q指向p这个普通的指针, * q 和p访问的是同一块内存,如果我对 * q赋值,相当于是把内容写到这块内存中,*q存的是const int *,也就是把整型常量的地址是赋值给 *q,cosnt int b=20,可以把&b赋值给 *q,但是p是普通的指针啊,p可以解引用修改整个整型常量的地址啊,所以肯定不行啊!!!不能把常量的地址泄露给一个普通的指针!!!
在这里插入图片描述
在这里插入图片描述

相当于把这个整型地址放到普通的一级指针变量里面。
但是常量的地址赋值给普通的指针p(因为p和*q等价)了,这是不行的。

怎么改呢???
在这里插入图片描述
此时 *p不能被赋值了。就可以了。

还有一种写法:
在这里插入图片描述
让*q不能赋值。

总结应用

在这里插入图片描述
A错误,因为
在这里插入图片描述
B正确。
在这里插入图片描述
C正确。 const不参与类型。都是int*
D正确。
在这里插入图片描述
在这里插入图片描述
A错误。 把常量的地址给普通的指针了。
在这里插入图片描述
B正确。
在这里插入图片描述
C正确。
在这里插入图片描述
D错误。
在这里插入图片描述
在这里插入图片描述
E错误。
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值