常量

编程语言 / const

本地源文件:docs/lang__const.md

常量

C++ 定义了一套完整的只读量定义方法,被 const 修饰的变量都是只读量,编译器会在编译期进行冲突检查,避免对只读量的修改,同时可能会执行一些优化.

在通常情况下,应该尽可能使用 const 修饰变量、参数,提高代码健壮性.

const 类型限定符

常量

const 修饰的变量在初始化后不可改变值

---|---

### 常量引用、常量指针

常量引用和常量指针均限制了对指向的值的修改

---|---

另外需要区分开的是常量指针(const t)和指针常量(t const),例如下列声明

---|---

在函数参数里使用 `const` 限定参数类型,可以避免变量被错误地修改,同时增加代码可读性

---|---

const 成员函数

类型中 const 限定的成员函数,可以用来限制对成员的修改.

---|---

## 常量表达式 `constexpr`(C++11)

常量表达式是指编译时能计算出结果的表达式,`constexpr` 则要求编译器能在编译时求得函数或变量的值.

编译时计算能允许更好的优化,比如将结果硬编码到汇编中,消除运行时计算开销.与 `const` 的带来的优化不同,当 `constexpr` 修饰的变量满足常量表达式的条件,就强制要求编译器在编译时计算出结果而非运行时.

更直观的理解是把 `const` 理解成「只读」,`constexpr` 理解成「不可变」

---|---

以下例子很好说明了 constconstexpr 的区别,代码使用递归实现计算斐波那契数列,并用控制流输出.

实现

---|---

编译后的可能的汇编代码(使用 Compiler Explorer,Clang 19)

---|---

constexpr 修饰的 fib0 函数在唯一的调用处用了常量参数,使得整个函数仅在编译期运行.由于函数没有运行时执行,编译器也就判断不需要生成汇编代码.

在同时注意到汇编中,v0 没有初始化代码,在调用 cout 输出 v0 的代码中,v0 已被最终结算结果替代,说明变量值已在编译时求出,优化掉了运行时运算. 而 v1 的初始化还是普通的 fib1 递归调用.

所以 constexpr 可以用来替换宏定义的常量,规避 宏定义的风险

算法题中可以使用 constexpr 存储数据规模较小的变量,以消除对应的运行时计算开销.尤为常见在「打表」技巧中,使用 constexpr 修饰的数组等容器存储答案.

编译时计算量过大会导致编译错误

编译器会限制编译时计算的开销,如果计算量过大会导致无法通过编译,应该考虑使用 const

---|---

使用 constexpr 时 Clang 给出的编译错误

---|---

参考资料

本页面最近更新: 2026/1/7 08:56:54,更新历史 发现错误?想一起完善?在 GitHub 上编辑此页! 本页面贡献者:cmpute, Tiphereth-A, Enter-tainer, ouuan, billchenchina, c-forrest, c0nstexpr, CCXXXI, CoelacanthusHex, gi-b716, HeRaNO, mgt, SakamotoKurome, StudyingFather, typed-sigterm, Xeonacid 本页面的全部内容在CC BY-SA 4.0SATA 协议之条款下提供,附加条款亦可能应用