C/C++中的常量指针与指针常量
常量指针和指针常量是两个经常出现的概念,今天做个小小总结。
文章各部分的内容都是很容易理解的,并且附加代码说明,一切的前提是理解文章2.1和2.2部分,所以搞好基础再往后看呐。觉得文章长的话,可以直接跳到最后的结论。
废话
最近在看VC++,看到书里有提这两个概念,学C的时候也有这两个概念,学C++的时候也有顶层const和底层const(这个我懂是懂,但从理解层次上不是那么懂为什么叫做顶层和底层)。所以就是这个知识点很常见啦,但似乎很多人很迷惑,或者说理解着不舒服。于是我的“神逻辑”就来了。
我对它们的理解
主要是翻译问题
常量指针、指针常量这种名词是英文翻译过来的,所以中文会有点拗口。常量的、指针的,我们生活中是没有这样的词的。
英文里是这样的两个东西:pointer to const, const pointer。
pointer是指针
的意思;const是constant的缩写,作名词是常量
的意思,作形容词是不变的
的意思。
这两个词:pointer to const, const pointer。中文有两种翻译方法:
翻译方法 | pointer to const | const pointer |
---|---|---|
第一种 | 指向常量的指针(常量指针) | 不变的指针(指针常量) |
第二种 | 指向常量的指针(指针常量) | 不变的指针(常量指针) |
说来说去都是翻译的问题。英文里很容易能看懂的意思,换成中文就有两种换法。
我赞成第一种翻译方法,因为它更符合中文习惯。
第二种方法确实不该有指针常量这个说法,太不合中文习惯。
所以要讨论中文版的话,如果出现指针常量,也应该是第一种方法。
下面是一篇讲常量指针和指针常量的文章:
https://www.thegeekstuff.com/2012/06/c-constant-pointers换成英文就不用玩文字游戏了
所以呢,本质上应该用英语去讲。但本篇是讲中文版的一种方法。(去百度也会发现有两种说法,原因是翻译不同)。
基础
本文用第一种说法,常指是pointer to const,指常是 const pointer。
常指、指常就是两个词而已,都是四个字。把前边的两个字当做形容词(是用来修饰后边的名词的),后边的名词才是重点。
指针就是地址嘛,常量就是不可以修改的量(初始化不算做赋值,不算做修改)。
注意区分指针本身(的内容)和指向的内存的内容。
修改指针即改变指针本身的内容,修改内存或者说修改内存内容就是修改指针指向的内存中的内容。这样讲的很清楚了吧.....…..
常量指针
常量指针中的常量呢,指的是这个指针的作用是常量性的、无权修改的,即不可以通过该指针修改内存中的内容,并不代表指向的内存不修改,注意前边有通过二字。
这个词也有指向常量的指针的叫法,我认为这个中文叫法是不准确的甚至是错误的。如果说常量指针是指向常量的指针,我认为这句话最直接的意思是说指针指向的内存是常量,这个意思是错误的,会误导他人,所以我不提倡这样叫它。证明参见文章3.3部分
在讨论问题的时候,互相知道对方说的是什么东西非常重要~,比如c++里的默认构造,没有构造函数这样的句子,不同人的理解方式不同,这些概念理解也是讨论进行的一个前提。
指针常量
这里的指针呢,指的是这个常量是一个地址。
如何根据定义判断类型
//代码1
const char * p; //常量指针
char const * p; //常量指针 跟上一句等效
char * const p; //指针常量
根据const和*的相对位置
const 在*左边=》常量指针;反之,指针常量。
根据谁离变量名近
const近=》指针常量;反之,常量指针。(const就是不变嘛,*就是指针,所以理解是很重要的,也就是2.1)
代码验证
常量指针
//代码2
//char ch[] = "HelloWorld!";
const char* pStr1=ch; //定义常量指针
//1.常量指针本身的值可以修改
pStr1 = nullptr; //correct
//2.不能通过常量指针修改它所指向的内存中的内容(注意通过二字,不要误会常量指针)
*pStr1 = 'h'; //error
*(pStr1 + 1) = 'E'; //error
pStr1[2] = 'L'; //error
指针常量
//代码3
//char ch[] = "HelloWorld!";
//指针常量(顶层const)
char * const pStr2 = ch; //定义并初始化
//1.是常量,不可以被赋值(不把初始化叫做赋值)
pStr2 = nullptr; //error
常量指针容易被误解的地方
//代码4
int n = 0; //定义变量n
const int * p1 = &n; //常量指针p1
int * const p2 = &n; //指针常量p2
*p1 = 3; //error 因为不能通过常量指针修改内存中的内容,划重点!:但这不是说指向内存中的内容不可修改
n = 3; //correct 这是对的,因为n是变量啊
*p2 = 3; //correct 指针常量部分的代码就有体现,不多说
//代码5
const int n = 0; //定义变量n
const int * p1 = &n; //常量指针p1
int * const p2 = &n; //error 错误的 原因见下-指针间的赋值
*p1 = 3; //error 原因是常指不可修改内存
n = 3; //error 原因是n是变量
代码4和代码5中的常量指针p1都不能改变内存中内容,但内存中内容是否可修改是不一定的。(代码4的第5第6行要好好看)
原因是:常量指针不可以修改内存是因为不可以通过常量指针修改内存所致(你不通过常量指针的话,变量是否可以修改就不一定了)
结论
常量指针
在这里指pointer to const。指针作用是常量性的,不可以通过它修改指向内存(容易被误会成内存一定不可修改)。
指针常量
英文里指const pointer。指针是一个常量,指针本身不可以被修改。
作者:@臭咸鱼
本文为作者原创,转载请注明出处:https://www.cnblogs.com/chouxianyu/p/11269993.html
欢迎转发和评论