C++ 指针常量与常量指针

吐槽一下: 指针常量与常量指针的翻译就好比机器学习中Regularization翻译成正则化一样,讲真,正则化这个说法确实要比规则化显得高端些,但是到了理解的时候,还是要按照规则化理解。

指针常量与常量指针这个概念是一样的,英文里没有pointer const这个词,只有pointer to const和const pointer这两个词。

而不管是指针常量还是常量指针他们的区别其实就是const关键字的位置,下面直接根据声明方式不同解释二者的区别: 在只有一个关键字const的情况下,声明有三种方式:

//1
const int* p;
//2 
int const* p;
//3 
int * const p;

其中1和2是一种,这种情况下不能使用指针修改指向数据的值,但是也仅仅是不能使用指针p修改而已,p指向的值本身如果不是常量的话那么还可以直接对值修改,举个例子:

int a = 5;
const int* p = &a;
a = 4;//合法
*p = 3;//不合法

由于这个特点,通常把const int* p的形式作为函数的参量,以表示函数不会用这个指针修改数据,比如我们有一个子函数是想打印一个数组,那么我们可以将函数声明写成这样:

void printfarr(const int *arr,int n);

如此,当主函数中调用该子函数,并打印主函数中的变量array的时候,永远不会出现array变化的情况,但是主函数自身想要修改array显然是可以的。所以被指向的数据的值到底能不能改变根本不由指针的声明方式决定,而是该数据本身是常量还是变量

int a = 5;
const int b = 5;
const int* p = &a;
a = 4;//合法
*p = 3;//不合法
p = &b;//合法
b = 4;//不合法
*p = 3;//不合法

而对于3,它的作用是保证指针不会指向别处,也就是一旦用这种方式声明并初始化,指针指向的地址永远不会发生变化,但是其中的值却可以通过指针改变:

int a = 5;
int b = 6;
int * const p = &a;
*p = 4;//合法
p = &b;//不合法

以上就是所谓的指针常量与常量指针所包含的概念,在这里标个号: 1,2暂时称为第一类,3暂时称为第二类,那么第一类和第二类到底哪个叫做指针常量,那个叫做常量指针呢?说实话我都不知道指针常量与常量指针的叫法是不是够官方,我只能说概念非常混淆,而且其实它的两个名字并不重要,关键的是声明方式与作用的区别。

百度百科认为第一类应该叫做常量指针,第二类叫做指针常量

但是在《C Primer Plus》中将第一类叫做指向常量的指针,也就是在文章开头提到的pointer to const,那么第二类也就是const pointer了,但是这样一来,他就已经和百度百科的说法反了。

到目前为止我还没有找到更权威的说法,维基百科找不到这两个词,所以我们干脆不要去理会第一类与第二类到底该叫做什么名字,因为他们的声明方式与作用是决定清晰的就足够了。

上面说的情况,对于指针的修饰都只用了一个const关键字,还有两个const一起用的时候,此时的结果就是指针不能修改指向的数据,指针不能指向别的地方:

int a = 5;
int b = 6; 
const int * const p = &a;//合法
*p = 4;//不合法
p = &b;//不合法
a = 7;//合法

最后还有一个最严格的情况,就是数据本身就是常量,而且常量的地址不允许赋值给普通指针,这样一来数据自身不能改变,指针不能该数据,指针不能指向别处。

const int a = 5;
int b = 6; 
int * const q = &a;//不合法
const int * const p = &a;//合法
*p = 4;//不合法
p = &b;//不合法
a = 7;//不合法    

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏领域驱动设计DDD实战进阶

04-TypeScript中的方法新功能(上)

在TypeScript中,提供了一些函数的新功能,能够简化JavaScript中的一些比较复杂代码才能实现的一些能力。 在C#后端语言中,能够对方法传递的参数指...

2564
来自专栏C语言及其他语言

【每日一题】问题 1195: 去掉双斜杠注释

输入数据中含有一些符合C++语法的代码行(每行代码不超过200个字符)。需要说明的是,为了方便编程,规定双斜杠注释内容不含有双引号,源程序中没空行。

762
来自专栏Android知识点总结

html5常用控件

1092
来自专栏性能与架构

ZooKeeper 实例 - Leader 选举

Leader 选举用于保证系统的高可用,例如一个重要服务,为防止其出现故障使服务中断,同时准备好另外2个备用,这就需要从3个服务节点中选出一个对外服务,这个服务...

3506
来自专栏左瞅瞅,右瞅瞅

SaltStack——配置管理小试(jinja使用)

https://docs.saltstack.com/en/latest/ref/modules/all/

1766
来自专栏游戏杂谈

JavaScript正则表达式的零宽断言

有类似如下的应用场景,一个全为数字的字符串,现在要将它每三位使用“,”进行分隔。例如:1099795448 –> 1,099,795,448。这里就可以使用正则...

824
来自专栏数据之美

python基础(4):Python读写文件实际操作的五大步骤

from: http://developer.51cto.com/art/201003/187960.htm Python读写文件在计算机语言中被广泛的应用,如...

2836
来自专栏领域驱动设计DDD实战进阶

07-TypeScript的For循环

在传统的JavaScript中,关于循环,可以有两种方式,一种是forEach,一种是for。 forEach的用法如下: var sarr=[1,2,3,4]...

2774
来自专栏King_3的技术专栏

leetcode-561-Array Partition I

1817
来自专栏技术小站

找第一个只出现一次的字符

给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符。如果没有,输出no。

1381

扫码关注云+社区