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 条评论
登录 后参与评论

相关文章

来自专栏前端知识分享

第158天:面向对象入门

在这里我们可以理解为创造对象的几种模式:单例模式,工厂模式,构造函数模式,原型模式等。

772
来自专栏HTML5学堂

伪数组

HTML5学堂:熟悉JavaScript的人对document.getElementsByTagName再熟悉不过,对arguments也多有耳闻,我们时常针对...

2764
来自专栏Danny的专栏

正则表达式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

1542
来自专栏LEo的网络日志

c库函数strncat出现乱字符

3667
来自专栏小樱的经验随笔

【正则表达式学习笔记之一】简单认识正则表达式

一、引言   正则表达式是什么东东?   在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句...

1953
来自专栏文武兼修ing——机器学习与IC设计

JavaScript入门笔记(2)字符串相关列表对象

字符串相关 字符串基础 字符串历来是各种编程语言坑最多的地方(个人认为),不同软件语言在字符串上的操作的差别比软件语言和硬件描述语言的差距都大(一样是个人认为)...

3036
来自专栏吴伟祥

正则表达式30分钟入门教程 转

学习正则表达式的最好方法是从例子开始,理解例子之后再自己对例子进行修改,实验。下面给出了不少简单的例子,并对它们作了详细的说明。

802
来自专栏梦魇小栈

重新介绍 JavaScript(JS全面系列教程)

为什么会有这一篇“重新介绍”呢?因为 JavaScript 堪称世界上被人误解最深的编程语言。虽然常被嘲为“玩具语言”,但在它看似简洁的外衣下,还隐藏着强大的语...

921
来自专栏知识分享

(四)Lua脚本语言入门

这篇文章就当成铺垫型的文章,写着写着发现有好多想写的,,关于C#与Java,当然作为铺垫肯定与Lua的下部分介绍有关..... 对于"泛型",先看C#中"泛型"...

3705
来自专栏移动端开发

Swift 面向对象解析(二)

 接着上面一篇说的内容: 一 继承:      苹果继承与水果,苹果是水果的子类,则苹果是一种特殊的水果;这就是继承的关系,这个我们学OC的时候相信也都理解了...

2187

扫码关注云+社区