C++使用类型修饰符const来定义常类型,常类型的变量或对象的值是不能被更新的。不管出现在任何上下文都是为这个目的而服务的。由于该关键字比较容易出错,因此做笔记区别该关键字的用法。
以最简单的int类型举例,const对于一个普通的int型变量的定义方式为:
const int x = 3;
x = 66; //语法错误
std::cout << "x = " << x << std::endl;
该表达式说明x本身是一个变量,由const修饰变成了一个常量,x值便无法再进行修改。注释掉语法错误的行,代码输出结果为:
x = 3
以上过程记为:
变量名 | 存储地址 | 存储内容 |
---|---|---|
x | &x | 3(不可修改) |
const与指针的合作使用方法有多种,以下是几种常见的方式:
其中,在表达的意义上,1和2、4和5完全等价,可以归为两类,3与其它4种有所不同,将以上5种情况分成以下三种情况讨论:
第一种情况:const在*前面
int x = 33;
int y = 44;
const int *p = &x;
p = &y; //语法正确
*p = 55; //语法错误
std::cout << "x = " << x << std::endl;
std::cout << "*p = "<< *p << std::endl;
原因:const修饰的是*p,p表示指向const int型数据的指针,指向可以改变,但不可以通过p改变指向地址上的值,因此*p是一个常量,*p的值不可以再修改,也就是无法通过修改*p的值来修改x的值。注释掉语法错误的行,代码输出结果为:
x = 33
*p = 44
以上过程记为:
变量名 | 存储地址 | 存储内容 |
---|---|---|
x | &x | 33 |
p | &p | &y |
第二种情况:const在*后面
int x = 33;
int y = 44;
int* const p = &x;
p = &y; //语法错误
*p = 88; //语法正确
std::cout << "x = " << x << std::endl;
std::cout << "*p = "<< *p << std::endl;
原因:const在*后面,在p的前面,修饰的是p,表示p是指向int型数据的const指针,因此p不可以再指向其他地址,但是它指向了x,可以通过*p来修改x的值。注释掉语法错误的行,代码输出结果为:
x = 88
*p = 88
以上过程记为:
变量名 | 存储地址 | 存储内容 |
---|---|---|
x | &x | 33 |
p | &p | &x(不可修改) |
第三种情况:*的前后都有const
const int x = 33;
int y = 44;
const int* const p = &x;
p = &y; //语法错误
*p = 88; //语法错误
std::cout << "x = " << x << std::endl;
std::cout << "*p = "<< *p << std::endl;
原因:*前后都有const,说明p是一个指向const int的const指针,因此p的指向和指向地址上的值都不可变。注释掉语法错误的行,代码输出结果为:
x = 33
*p = 33
以上过程记为:
变量名 | 存储地址 | 存储内容 |
---|---|---|
x | &x | 33(不可修改) |
p | &p | &x(不可修改) |
来看一组以下的const与引用
int x = 33;
const int &p = x;
x = 100; //语法正确
p = 1000; //语法错误
std::cout << "x = " << x << std::endl;
std::cout << "p = "<< p << std::endl;
原因:x是一个普通变量,可以修改自身的值,但是p是一个const类型的引用,不能修改自身的值,只能获取x的值。注释掉语法错误的行,代码输出结果为:
x = 100
p = 100
以上过程记为:
变量名 | 存储地址 | 存储内容 |
---|---|---|
x | &x | 33 |
p | &p | x(只能获取x的值) |
再来看一组const与引用
const int x = 33;
const int &p = x;
x = 100; //语法错误
p = 1000; //语法错误
std::cout << "x = " << x << std::endl;
std::cout << "p = "<< p << std::endl;
显然x与p都是const类型,无法修改自身的值,因此输出结果为:
x = 33
p = 33
以上过程记为:
变量名 | 存储地址 | 存储内容 |
---|---|---|
x | &x | 33(不可修改) |
p | &p | 33(不可修改) |
综上,const的使用符合就近原则,注意以下关于p和q写法是错误的:
const int x = 33;
int *p = &x;
int &q = x;
原因:x是const int型,其值不能被修改,不能通过非const类型的*p或者&q去指向引用x,因此编译器会直接报错,在第二句和第三句的前面加上const则能直接通过。