区分const int * , int const *, int * const
const int * p = 1
表示变量p所指的对象是不变的,p是可以改变的,即*p = 1
不可以改变,但p的地址可以改变;int const * p = 1
同上;int * const p = 1
表示变量p不可以改变,即地址不变,但所指的对象可以改变。
底层和顶层const
概念区分
顶层const
:指const
所修饰的变量本身是一个常量,自身无法更改;例如上述int * const p = 1
,其中p
的值无法更改,所以是一个顶层const
;
底层const
:指const所修饰的变量所指的对象是一个常量,变量自身可以改变;例如上述const int * p = 1
或者int const * p = 1
,p的值是可以改变的,但是*p
不可以改变。
作用区分
按照常识,一个非常量可以赋值给另一个非常量和一个常量;但是一个常量只能赋值给另一个常量,因此在此处也是如此。
当执行拷贝操作时,顶层const
不受影响,但是底层const
的只能拷贝到底层const
。
在下方我们会看到一个矛盾却又不矛盾的例外
`const int j = 2` 或者是`int const j = 2`
在《C++ Primer》 第五版中,他告诉我们这是一个顶层const
,似乎不难理解,毕竟j
的本身是一个常量。但是当我使用下面语句赋值时,
`int* const p2 = &j`
编译器报错了,他告诉我"const int *" 类型的值不能用于初始化 "int *const" 类型的实体
不过虽然违背了我们之前所讨论的,但是如果单单将const int j = 2
看做一个常量,似乎又不难理解了,毕竟,常量无法初始化一个非常量。
上述是我的粗浅理解,如果各位大佬有不同的理解,请告诉我,感谢!
void test()
{
int i = 1;
int const j = 2; //j 的值不可以更改,这是一个顶层const
int* const p1 = &i; //const修饰的是p本身,不能改变p1的值,其是一个顶层const
int const * p3 = &j; //const 修饰的是p3所指的对象
p3 = &i; //p3的值可以改变
int * const p4 = p1; //顶层const 赋值给 顶层const
int const * p5 = p1; //顶层const 赋值给 底层const
int const * p6 = p3; //底层const 赋值给 底层const
//int * const p7 = p3; //不能将一个底层const 赋值给 顶层const
//例外在于 j = 2
//int* const p2 = &j; //此处会报错
}