1 指针常量
指的是指针本身是一个常量,必须初始化,也不能改指向别的对象。
能否通过指针改变指向对象的值取决于指向的对象是否是常量。
int a=1;
int *const ptr=&a;
(*ptr)=100;//可以,a不是一个常量
2 常量指针
const int *ptr
int const *ptr
指向常量的指针并没有规定其所指向的对象必须是一个常量,也就是可以指向一个const限制的,也可以指向一个普通的变量;所谓指向常量的指针,仅仅要求不能通过该指针改变对象的值,而没有规定那个对象不能通过其他途径改变。
但是要注意:一个常量不能用一个普通指针指向他,自己试的可以通过编译,但是会报warning
const double pi = 3.14;
double *ptr = π//错误的
const double *cptr=π//正确
*cptr=44;//错误
double a=11;
cptr=&a;//正确
3 顶层const与底层const
- 顶层const:指针本身是一个常量,也就是指针常量
- 底层const:指针所指的对象是一个常量
- 顶层const也可以表示任意的对象是常量
- 用于声明引用的const都是底层const
int i=0;
int *const p1 =&i;//顶层const,本身的值不可变
const int c=33;//顶层const,c的值也不可变
const int* p2=&c;//底层const,p2的值可变
要注意非常量可以转化成常量,反之不行
4 常量引用
常量引用和常量指针一样,没说引用或指向的一定得是常量,只是说不能通过该引用或者指针来改变引用或指向的对象,但是这个对象可以通过其他方式改变(如果不是常量的话)。
同样的,不能用一个普通的引用来引用一个常量。
5 常量表达式
定义:指值不会改变并且在编译过程中就能得到计算结果的表达式。
const int i=20;//is const expression
const int j=i+1;//is ...
int x = 20;//is not a const expression
const int ss=get_ss()//is not a...,编译是不能确定
constexpr类型
声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化
constexpr int mf = 20;//20是常量表达式
constexpr int limit = mf+1;//mf+1是常量表达式
constexpr int sz = size();//只有当size()是一个constexpr函数时,才是一条正确的声明
constexpr修饰指针仅与指针有关,而与指向的对象无关,就是个指针常量
const int *p=nullptr;//p是一个指向整常量的指针,常量指针
constexpr *q=nullptr;//q是一个指向整数的常量指针,指针常量
constexpr指针不能指向放在函数体内的变量,引用也不可以,必须是全局变量。
int i=100;
int main()
{
int j=100;
constexpr int *p=&i;//right
constexpr int *q=&j;//wrong
constexpr int &t=i;//right
constexpr int &y=j;//wrong
}