顶层const意味着被修饰的对象本身是一个常量。
顶层const可以用来修饰基本数据类型(如int、float等)和自定义类型(如结构体、类等)的对象。
顶层const修饰的对象的值不能被修改,但是该对象可以被赋予另一个值(如果它是可以被赋值的对象,例如非引用类型的变量)。对于指针来说,如果它是顶层const,那么指针本身(即指针的地址)不能被改变,但指针所指向的内容可以改变。
当顶层const修饰一个指针时,它表示的是指针本身(即存储的地址)是一个常量,不能指向其他地址。但请注意,这并不影响指针所指向的数据内容是否可以被修改!
const int b = 42;//ci的值不能改变,const是顶层的
int i = 10;
int* const p = &i;//p是const顶层指针,p的值(即p指向的地址不能修改),但是*p(p指向的内容)可以修改
*p = 8;
底层const表示被const修饰的值或对象所指向的内容是不可修改的,即无法通过该指针或引用来改变其所指向对象的值。
底层const主要用来修饰指针或引用类型。
对于指针来说,如果它是底层const,那么指针所指向的内容不能被修改,但指针本身(即指针的地址)可以改变。这意味着你可以让指针指向另一个对象,但不能通过该指针修改它所指向的对象的值。
int x = 10;
const int* p = &x;//底层const指针
*p = 5;//错误表达式必须是可修改的左值
区分顶层还是底层:(以右为尊)
指针类型:对于指针来说,可以通过const关键字在符号的位置来判断是顶层const还是底层const。如果const在符号的左边,那么它是底层const;如果const在符号的右边(或者没有“”符号,直接修饰变量),那么它是顶层const。
int* const p = &a;//p是顶层const指针,p的值不可以修改,但*p可以修改
const int* p = &a;//p是底层const指针,*p不可以修改,但p的值可以修改
引用类型:对于引用来说,由于引用一旦被初始化后就不能改变其指向的对象,因此所有的const引用都可以看作是底层const。这是因为引用本身就像是一个“常量指针”,其指向的对象在初始化后就不能被改变(尽管引用的语法和指针不同,但在这个上下文中可以这样理解)。