【背景】
在c中,有个基本数据类型:指针,还有一个修饰词:常量(const),这两个分开看,都比较简单,但是一旦结合后,就有些让人容易混淆,结合后就是:指针常量,常量指针,下面我们进行分析这两个结合后的类型的具体差别和使用方法
【分析】
1.指针
定义:存放变量地址的变量
再看看百度给的解释,如下:
指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。 [1]指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体
总结下,上面这么一大段话其实主要说的就是3点:
1.1 指针也是一个变量,但是这个变量是用存储其他变量的地址的,并不是像其他类型的变量一样,可以存储数据值,字符串值等,这个变量只能存其他变量的地址,也就是内存地址
1.2 在同一个cpu架构下,所有指针变量本身所占的单元存储长度是相同的,比如:int *p; char *pr; long *lt等;在同一cpu架构下,上面的指针所占的内存都是一样的长度(4字节)
1.3 指针变量是存储地址的,所以像函数地址,数组地址,常量地址等都可以存在指针变量里,所以就有了指针函数、函数指针、指针常量、常量指针、指针数组、数组指针等容易混淆的类型
2.常量(const)
定义:const修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的
目的:const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点
再看看百度的解释,如下:
const是一个C语言(ANSI C)的关键字,具有着举足轻重的地位。它限定一个变量不允许被改变,产生静态作用。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一定帮助。另外CONST在其它编程语言中也有出现,例如Pascal、C++、PHP5、B#.net、HC08 C、C#等
总结下,上面这些话的意思就是两点:
1.const所修饰的是常量,不允许被再修改的,是固定的值
2.提高程序的安全性和可靠性
好的,以上是关于指针和常量的定义及解释的剖析和总结,那么下来我们进入主题,分析下这两个结合后的效果
3.指针常量
格式:char* const str //指针类型 + const + 指针名
可以看出const修改的是指针名,那么想一想:这个指针名被const修饰,是什么意思?(这点至关重要哦)意思是:我const修改你指针名了,那么也就是说你这个指针就只能指向一个地址了,不能再指向其他地址了,简单来说就是指针指的内存方向被固定死了,就像开车一样,方向盘被固定死了,就只能往一个方向开了,可否理解?再回味思索下,这个意思哦!
那么下面我们验证下,如下:
【验证1:改变指向:不可行】
报错如下:
可以看出,我们在后续的操作中,是无法改变指针p的指向的哦,不然就会报错,这个也就说明了我们的分析是对的哦,这个指针常量,是不允许后续再改变指针的指向的哦,那么,指针所指向变量的值是否可以改变呢?我们再看如下验证:
【验证2:改变内容,可行】
输出结果:
通过上面的验证,我们可以看出,指针常量是允许对所指向变量的内容进行改变的哦,为什么呢?因为const修改的是指针名,也就是说指针指向是固定的,但是所指向变量的内容并没有用const修饰,所以我们才可以改变的哦
【指针常量总结】
1.格式:char* const str //指针类型 + const + 指针名 (const修饰的是指针名哦)
2.本质是一个常量,但是类型是指针类型的,所以就是指针常量,这个指针常量只能固定的指向一个方向,后续不能再被修改指向
3.指针指向地址的内容是可以被修改的,可以通过指针解引用赋值修改,也可以通过原来指向的变量赋值进行修改,都是可以的
口诀:常量修饰指针名,方向固定是本能,变量内容随便改,敢动方向就不行
4.常量指针
格式1:int const *p //格式:类型 const *指针名
格式2:const int* pa //格式:const 类型 *指针名
可以看出,cosnt修饰的是数据类型,且在*前面,所以这个明显就是没有修饰指针名,什么意思呢?意思就是说:const修饰的是指针指向的那个变量的值,所以说变量的值不能被修改,但是指针的指向可以改变哦!是不是有点懵?没事,再屡屡思路,或者我们直接看下面的验证代码,就明了了,如下验证:
【验证1:改变内容:不可行】
【验证2:改变指向:可行】
输出结果:
【常量指针总结】
1.两种格式,如下:
格式1:int const *p //格式:类型 const *指针名
格式2:const int* pa //格式:const 类型 *指针名
2.本质是一个指针,指向一个常量值,所以是常量指针,但是这个指针可以改变方向,后续可以任意指向其他变量的地址,因为const并未修改指针名,所以是常量指针
3.指针指向的变量的内容不可以通过指针进行改变,只能通过原来的变量进行改变
口诀:常量修饰类型名,方向随意是本能,指针不准改内容,变量内容改就行
【总结】
1.看const和*的位置而定,const在*前的,就是常量指针,const在*后的,就是指针常量(个人理解最好)
2.口诀:(个人不推荐,最好是理解)
常量指针:常量修饰类型名,方向随意是本能,指针不准改内容,变量内容改就行
指针常量:常量修饰指针名,方向固定是本能,变量内容随便改,敢动方向就不行
3.多用多练多温故知新,才是王道,其他都是浮云,伙计们!