在编写程序时,像角色当前的血量、考试的得分这类数据,会随着程序运行不断变化。但还有一些数据,比如圆周率 3.14、一年有 12 个月、试卷满分 100 分,从定下来的那一刻起就不应该再改动。
如果把这些固定不变的数据也存放在普通的变量里,万一后面写代码时不小心改掉了它,程序计算就会出错。为了解决这个问题,C++ 提供了 “常量”,也就是值从定义开始就固定不变、直到程序结束都不会改变的量。
C++ 常量语法
在 C++ 中,定义常量最常用的方式是在数据类型前面加上 const,并赋上初始值。
语法:
const 数据类型 常量名 = 初始值;说明:
其中,const 是英文单词 “constant(恒定的、常量)” 的缩写,它是 C++ 专门用来定义常量的关键字。比如 const int maxCount = 10; 就表示定义了一个名为 maxCount 的整型常量,它的值固定为 10。
给常量起名字的规则跟普通变量是一样的。在实际开发中,除了像 maxCount 这样使用小写字母开头之外,很多程序员也习惯全部使用大写字母并用下划线连接,比如 MAX_COUNT、PI,别人看一眼名字就知道它是一个常量。
在使用 const 定义常量时,小伙伴们需要注意以下 2 个特点:
- 定义时必须同时初始化:普通变量可以先定义、等到后面再赋值,而
const常量一旦创建就不能再修改了,所以在定义的同时必须给出初始值,否则编译器会直接报错。 - 初始化后不能再修改值:常量定义好之后,我们可以读取它的值,或者拿它参与算术计算,但不能再把它放到等号(=)左边去修改它的值。
C++ 常量示例
接下来,我们通过几个简单的例子来看看 C++ 常量具体是怎么使用的。
示例 1:定义并输出常量
#include <iostream>
int main() {
const int maxCount = 10;
std::cout << maxCount;
return 0;
}运行结果如下。
10分析:
const int maxCount = 10; 表示定义了一个整型常量 maxCount,并将其初始化为 10,随后使用 std::cout 将它的值输出到屏幕上。
定义 const 常量时千万不要漏掉初始值。如果只写出类型和名字却不赋初值,编译时就会直接报错:
// 正确方式
const int maxCount = 10;
// 错误方式
const int maxCount;提示 我们在阅读他人代码时,有时会见到 int const maxCount = 10; 这种把 const 放在类型后面的写法,它与 const int 的作用完全一样。在实际开发中,统一把 const 写在最前面即可。
示例 2:使用常量参与计算
#include <iostream>
int main() {
const double PI = 3.14;
double radius = 5.0;
double perimeter = 2 * PI * radius;
std::cout << perimeter;
return 0;
}运行结果如下。
31.4分析:
在这个例子中,圆周率和半径都带有小数,因此我们使用了表示小数的 double(双精度浮点型),它是 C++ 中常用的基础数据类型。算式中的星号(*)代表乘号,2 * PI * radius 就是计算圆的周长。
需要注意的是,const 限制的只是 “不能修改常量自身保存的值”,而读取它的值去参与运算是完全正常的。计算完成后,常量 PI 里面的值依然是 3.14。
与直接在算式里写数字 3.14 相比,专门定义一个 const 常量主要有以下 2 个好处:
- 代码含义更清晰:写出
PI或maxCount,任何人看一眼名字就知道这个数字代表圆周率或数量上限,比在代码里直接写一串陌生的数字好懂得多。 - 方便统一修改:假如程序里有 10 个地方都用到了圆周率
PI,后来希望把精度从 3.14 提高到 3.14159,我们只需要修改开头定义常量的那一处代码就可以了,不用满篇去翻找替换。
那如果我们在后面的代码里强行修改常量的值,会发生什么情况呢?下面我们来看一个例子。
示例 3:常量不能修改
#include <iostream>
int main() {
const int maxCount = 10;
maxCount = 20; // 尝试修改常量的值
std::cout << maxCount;
return 0;
}运行结果如下。
(报错)error: assignment of read-only variable 'maxCount'分析:
maxCount = 20; 这句代码尝试给常量 maxCount 重新赋值。由于 const 常量是只读的,不允许在初始化之后再次修改,编译器会直接报错,提示 “不能向只读变量 maxCount 赋值”。
在实际开发中,判断使用普通变量还是 const 常量,标准其实很明确:运行过程中会变化的数据,比如得分 score、年龄 age,使用普通变量。一旦定下来就不应该改动的数据,比如圆周率 PI、人数上限 maxCount,就加上 const 定义为常量。
常见问题
1. 在一些老代码中见过使用 #define 定义常量,它和 const 有什么区别?
在 C 语言和早期 C++ 代码中,有时会使用 #define PI 3.14 这样的宏定义来表示常量。不过 #define 只是在编译前做简单的文本替换,没有数据类型,编译器也无法对它做类型检查。
而在 C++ 中,使用 const 定义的常量具有明确的数据类型和作用范围,更加安全规范。因此大家平时定义常量时,优先使用 const 就可以了。
2. 有时候还会看到 constexpr 关键字,它和 const 有什么关系?
constexpr 是 C++11 引入的关键字,用来定义 “编译期常量”,要求常量的值在代码编译阶段就必须能算出来,比如写成 constexpr int maxCount = 10; 也是合法的。
对于初学的小伙伴来说,现阶段先掌握最通用的 const 就可以了,等学到后面的现代特性章节时再进一步了解 constexpr。
