0x00 const * ?
首先先看下面这几条语句:
const int *p
int const *p
int *const p
const int *const p
接下来我们来思考一下,这四条语句的const分别修饰那个呢?
0x01 变量类型
我们都有使用指针变量的时候,那么我们是把*
放在哪呢?
比如 int *p
还是 int* p
?
虽然这两种写法都能够表示声明一个名称为p
的int
类型的指针
我在Google-c++ 编码风格指南 上也看到*
贴哪边都可以
在声明指针变量或参数时, 星号与类型或变量名紧挨都可以
// 好, 空格前置.
char *c;
const string &str;
// 好, 空格后置.
char* c;
const string& str;
他们就真的没什么区别吗?
其实可以这样来理解:
我们写出一个变量声明int *p
把他的左边部分当作他存放的数据的类型 也就是int
右边当作这个int
的代号也就是*p
那么以后我们就这样来分
类型 名称
(int) (*p)
那么*p
的数据类型就是int
了
好另一个写法
int* p
同样来这样分
(int*) (p)
那么 p
的数据类型就是int*
了 也就是指针
0x02 如何区分const的修饰对象
ok 我们能够鉴别出类型之后,接下来我们就要看看前面给出的4条语句
首先是const int *p
和 int const *p
他们两个的*
都是贴变量名的 那为啥会有两种写法?
先来看看const
修饰符都修饰哪个类型.
const int *p
里的const
是修饰int
的,也就是说这个int
值不可以改变
int const *p
里 const
是修饰*p
的 , 而*p
的类型是int
也就是说const
修饰的是int
, 那也是跟上面的一样int
值不可变
地址不可改变
好我们看看int *const p
这样写我们用之前的区分类型的方法来试试
(int*) const (p)
好 我们发现 p
的类型是int*
是个指针 这个指针是一个放地址的变量
很明显 const
修饰的是p
也就是修饰的类型是int*
也就是这个指针不可变 就是地址不可变
虽然地址不能改变,但是地址指向的int
的值是可以变的 毕竟const
修饰的只是一个地址而已.
我想地址不可变, 值也不可变该如何写呢?
是的,只要const
修饰谁,谁就不可变, 我们只要把这两个都给修饰了就可以了
const int *const p
这里就跟我们之前讲的有点出入了.
先进行类型分析
const (int*) const (p)
按照理论应该是这样划分的呀? 可这两个const
看起来都在修饰int*
类型呀.
其实这里应该这样来分
(const int) *(const p)
这样写虽然不是很正确,不过好理解 const
是修饰int
的 *(const p)
是int
类型
const p
中 p
又是int*
也就是说 const
既修饰int
的值 又修饰int*
地址
这就做到了地址不可变, 值也不可变
0x03 总结
const int *p
: 值不可变int const *p
: 值不可变int *const p
: 地址不可变, 那个地址的值可以变const int *const p
: 地址和值都不可变