C++const限定符

const限定符

希望定义的变量它的值不能被该被改变,就可以用const关键字对变量的类型加以限定,因为const对象一旦创建后其值就不能被改变,所以const对象必须初始化。
初始化和const

const int i = get_size();//正确:运行时初始化
const int j = 42;//正确:编译时初始化
const int k; //错误:k是一个未经初始化的常量

int i= 42const int ci = i;//正确:i的值被拷贝给ci
int j = ci;//正确ci的值被拷贝给了j;

1.const 的引用
可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称之为对常量的引用。对常量的引用不能被用作修改它所绑定的对象。

const int ci = 1024;
const int &r1 = ci;//正确:引用及其对应的对象都是常量
r1 = 42;//错误:r1是对常量的引用
int &r2 = ci;//错误:试图让一个非常量引用指向一个常量对象

引用类型必须与其所引用的对象的类型一致,但是有两个例外。第一种例外情况就是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用类型即可

int i = 42;
const int &r1 = i;//允许将const int& 绑定到一个普通int对象上
const int &r2 = 42;//正确:r2是一个常量引用
const int &r3 = r1 * 2;//正确:r3是一个常量引用
int &r4 = r1 * 2//错误:r4是一个普通的非常量引用

常量引用仅对可参与的操作做出了限定,对于引用的对象本身是不是一个常量未作限定。因为对象也可能是个非常量,所以允许通过其他途径改变它的值

int i = 42;
int &r1 = i;//引用r1绑定对象i
const int &r2 = i;//r2也绑定对象i,但是不允许通过r2修改i的值
r1 = 0;//r1并非常量,i的值修改为0
r2 = 0;//错误:r2是一个常量引用

指针和const
与引用一样也可以令指针指向常量或者非常量。类似于常量引用,指向常量的指针不能用于改变其所指对象的值。要想存放常量对象的地址,只能使用指向常量的指针:

const double pi = 3.14;//pi是一个常量它的值不能改变
double *ptr = π//错误:ptr是一个普通的指针
const double *cptr = π//正确:cptr可以指向一个双精度常量
*cptr = 42;//错误:不能给*cptr赋值

const指针
指针是对象而引用不是,因此就像其他对象类型一样,允许把指针本身定为常量。常量指针必须初始化,而且一旦初始化完成,则它的值(也就是存放在指针中的那个地址)就不能改变。把*放在const关键字之前用以说明指针是一个常量,这样书写形式隐含着一层意味,即不变的是指针本身的值而非指向的那个值:

int i = 0int *const curi = &i;//curi将一直指向i;i的值可修改

const double pi = 3.14;
const double *const pip = &pi//pip是一个指向常量对象的常量指针;pi的值可修改

顶层const
指针本身是一个对象,用名词顶层const表示指针本身是一个常量,而用底层const表示指针所指的对象是一个常量,顶层const可以表示任意对象是常量,底层const则与指针和引用等复合类型的基本类型部分有关。

int i = 0int *const p1 = &i;//p1指针本身是一个常量,不能该变p1的值,这是一个顶层const
const int ci = 42;//不能改变次的值,这是一个顶层const
const int *p2 = &ci;//p2所指的对象是一个常量,允许改变p2的值,这是一个底层const
const int *const p3 = p2;靠右的const是顶层const,靠左的是底层const
const int &r = ci;//用于声明引用的const都是底层const

constexpr和常量表达式
常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。

const int max_files = 20;//max_files是常量表达式
const int limit  = max_files + 1;//limit 是常量表达式
int staff_size = 27;//staff_size不是常量表示式,尽管它是常量,但它的数据类型是int而并非const int
const int sz = get_size(); //sz不是常量表达式,sz本身是一个常量,但它具体值运行时才能获取到,所以也不是常量表达式

声明constexpr类型的变量一定是一个常量,而且必须用常量表达式初始化

constexpr int mf = 20;//20是一个常量表达式
constepr int limit = mf + 1;//mf + 1是常量表达式
constepr int sz = size();//只有当size是一个constepr函数时才是一条正确的声明语句

指针和constepr
在constepr声明中如果定义了一个指针,限定符constpr仅对指针有效,与指针所指的对象无关

const int *p = nullptr;// p是一个指向整型常量的指针
consteptr int *q = nullptr;//q是一个指向整数的常量指针

p是指向常量的指针,q是一个常量指针,与其他常量指针类似,constepr指针既可以指向常量也可以指向一个非常量

constepr int *p = nullptr;//np是一个指向整数的常量指针,其值为空
int j = 0;
constepr int i = 42;//i的类型是整型常量,i和j都必须定义在函数体之外
constepr const int *p = &i;//p是常量指针,指向整型常量i
constepr int *p1 = &j;//p1是常量指针,指向整数j
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值