指向常量的指针
指向常量的指针,即
pointer to const
,即指针指向的是一个常量,你应该把这个词(指向常量的指针)当做一个整体来理解,而不是分开。(当然也有翻译成指针常量的,但我并不喜欢这种翻译方式)
1 | 通常也将指针本身是一个常量称为顶层 const,将指针所指的对象是个常量称为底层 const |
它的语法格式是 const
在 *
左边,这一点很重要,因为后面要讲的常量指针是 const
在 *
的右边。下面是它的基本语法格式
1 | const double pi = 3.14; // pi 是一个常量 |
下面我们举一个例子来进行具体的讲解
1 |
|

1 | const double pi = 3.14; // pi 是一个常量 |
答案显然是不行的,报错提示这是一个非法类型转换。
事实上,有这样的一个指向关系,指向常量的指针可以指向常量和非常量,而普通指针只能指向非常量,如下图所示。
对上图,从逻辑上是这么理解的,假设一个普通指针
common_pointer
指向且只能指向非常量
non_const_var
,通过对 common_pointer
的解引用,我们可以修改非常量 non_const_var
的值。但是如果普通指针 common_pointer
指向一个常量
const_var
,理论上来说,可以对普通指针
common_pointer
解引用而修改常量 const_var
的值,但常量又不能修改,所以普通指针只能指向非常量。
对于常量指针的逻辑亦是如此。 那么第二个问题是,cptr
指针指向的内容可以修改吗?显然也是不能修改的,因为它此时指向的是一个常量
1 | const double pi = 3.14; // pi 是一个常量 |
cptr
具有只读属性。特别的是,即使 cptr
指向的是非常量,它也不能修改这个非常量的内容(如下代码),仅记住一点即可,那就是
cptr
自己本身具有的属性就是只读的。 1 | double pi = 3.14; // pi 是一个变量 |
1 |
|
char *const p = greeting;
下面我们用一张图来解释什么叫“指针的值(指针本身的内容)不能被修改”
虽然这幅图已经说明了一切,但我们还是不妨用代码来进一步解释
1 |
|
但是 cptr 指向的内容却是可以改变的,这和
pointer to const
不同
1 | double pi = 3.14; // pi 是一个变量 |
对比指向常量的指针与常量指针
也许直接记忆中文的话会很容易绕进去,不如直接记忆它们各自对应的英文会要很多,即指向常量的指针是
pointer to const
,常量指针是
const pointer
。
对于 pointer to const
来说,显然指针指向的是一个常量(当然它也可以指向一个非常量),对于
const pointer
来说,显然它自己是一个常量,即这个指针是一个常量,它蕴含的意思是这个指针指向的地址永远不可以改变,就好像你永远住在
xx 省 xx 市 xx 路 xx 号一样。
最后还是用一幅图来解释二者的联系与区别
红色区域是不能改变的值。
【注】在这幅图中,如果我们把 pi 改为非常量,即
double pi = 3.14
; 的形式,虽然依旧不能通过 cptr
来修改它的值,如 *cptr = 2.71 // error
,但是可以直接修改 pi
的值是没问题的,如
pi = 2.71; // right
。这一点我已经在上面的部分讲过,但在这里还想重复提一下。
1 |
|
1 | int main() |
const char** pcc = &pc;
位置会报错
error: invalid conversion from ‘char**’ to ‘const char**’
。原因是,我们的二重指针是
const
的,当 pcc 通过 pc 指向 c 后,逻辑上,我们不希望通过
pcc 来改变 c,但是,pcc 在指向 pc 的时候,pc 不是 const 的,意味着 pc
可以随时改变指针的指向。
上面的代码将 pc 设置为 const 就可以正常运行了
1 | int main() |