C++ 常量全面讲解

C++ 常量全面讲解

常量指程序运行期间值不能被修改 的量,C++ 分为字面常量const 常量、constexpr 常量、#define 宏常量、枚举常量几大类。


一、字面常量(直接写出的值)

程序中直接书写的数值、字符、字符串,本身就是常量,无法修改。

1. 整型字面量

cpp 复制代码
100;        // 十进制 int
012;        // 八进制(以 0 开头)
0x1A;       // 十六进制(以 0x/0X 开头)
100L;       // long 类型
100LL;      // long long 类型
100U;       // unsigned 无符号

2. 浮点字面量

cpp 复制代码
3.14;       // double(默认)
3.14f;      // float 单精度
3.14L;      // long double

3. 字符 & 字符串字面量

cpp 复制代码
'A';        // 字符常量,1字节
"hello";    // 字符串常量,末尾自带 '\0'
'\n';       // 转义字符常量

4. 布尔字面量

cpp 复制代码
true;
false;

特点:没有变量名,只能直接使用,不可赋值修改


二、#define 宏常量(预处理常量)

C 语言风格,C++ 兼容,预处理阶段直接文本替换

语法

cpp 复制代码
#define 常量名  值

示例

cpp 复制代码
#include <iostream>
#define PI 3.1415926
#define MAX_NUM 100

int main() {
    double r = 2;
    double s = PI * r * r;
    std::cout << s;
    // PI = 10;  // 报错,宏不能修改
    return 0;
}

优缺点

✅ 优点:使用简单,全局生效

❌ 缺点:

  1. 无类型检查,只是纯文本替换,易出bug
  2. 不具备作用域,全局污染
  3. 无法调试

C++ 不推荐优先使用 ,优先用 const/constexpr


三、const 修饰常量(C++ 核心常用)

1. 基本语法

cpp 复制代码
const 数据类型 常量名 = 值;

必须初始化,一旦定义,值永久不可修改。

基础示例

cpp 复制代码
#include <iostream>
int main() {
    const int a = 10;
    // a = 20;  // 编译报错:const 常量不可修改

    const double PI = 3.14159;
    std::cout << PI;
    return 0;
}

2. const 作用域

  • 局部 const:作用域仅限当前代码块
  • 全局 const:默认仅当前文件可见(和普通全局变量不同)

3. 结合指针(高频考点)

区分 const 修饰指针本身修饰指向的内容

cpp 复制代码
// 1. 常量指针:指向的值不可改,指针本身可改
const int* p1;
int x = 1, y = 2;
p1 = &x;
// *p1 = 100;  // 报错

// 2. 指针常量:指针本身不可改,指向的值可改
int* const p2 = &x;
*p2 = 100;
// p2 = &y;    // 报错

// 3. 双重 const:指针、指向的值都不可改
const int* const p3 = &x;

4. const 修饰函数参数/返回值

  • 形参加 const:保证函数内不会修改实参内容
cpp 复制代码
void func(const std::string& str) {
    // str = "abc"; 报错
}

四、constexpr 常量(C++11 新增,编译期常量)

constexpr 表示编译阶段就能确定值 的常量,比单纯 const 语义更明确。

1. 基本用法

cpp 复制代码
constexpr int NUM = 200;
constexpr double PI = 3.14159;

2. 和 const 的核心区别

  1. const

    • 可以是编译期常量 ,也可以是运行时常量

    • 允许用变量初始化:

      cpp 复制代码
      int a = 10;
      const int b = a; // 运行时确定值
  2. constexpr

    • 强制要求编译期确定值,只能用常量/常量表达式初始化

    • 可用于数组大小、模板参数等必须编译期求值的场景:

      cpp 复制代码
      constexpr int len = 10;
      int arr[len]; // 合法,C++ 要求数组大小为编译期常量

3. constexpr 函数(C++11 起)

函数也可声明为 constexpr,编译期就能计算结果:

cpp 复制代码
constexpr int add(int a, int b) {
    return a + b;
}
int arr[add(2,3)]; // 合法

总结:

  • 单纯定义常量:C++11 及以后优先用 constexpr
  • 仅做只读保护(运行时确定值):用 const

五、枚举常量 enum

用枚举定义一组相关整型常量。

1. 普通枚举

cpp 复制代码
enum Color {
    RED,    // 默认 0
    GREEN,  // 1
    BLUE    // 2
};
// RED、GREEN、BLUE 都是整型常量
int a = RED;

2. 手动指定值

cpp 复制代码
enum Num {
    ONE = 1,
    TEN = 10,
    HUNDRED = 100
};

3. 强类型枚举 enum class(C++11 推荐)

解决普通枚举隐式转 int、命名冲突问题:

cpp 复制代码
enum class Week {
    MON, TUE, WED
};
Week w = Week::MON; // 必须加作用域

六、const / #define / constexpr 对比表

方式 类型检查 作用域 求值时机 推荐度
#define 全局 预处理 不推荐
const 局部/文件 编译/运行 兼容旧代码
constexpr 局部/文件 编译期 C++11+首选

七、补充规则

  1. 常量定义后绝对不能赋值修改,编译直接报错;
  2. 全局常量建议放在头文件,配合 const/constexpr 使用;
  3. 数组、模板参数等场景,必须使用编译期常量constexpr 或字面量);
  4. 字符串常量存放在只读数据区,禁止通过指针修改内容。
相关推荐
小bo波14 小时前
Java Swing 图形用户界面实验 —— 从算术练习到游戏开发的完整实践
java·课程设计·gui·游戏开发·扫雷·swing
咖啡八杯16 小时前
GoF设计模式——备忘录模式
java·后端·spring·设计模式
apocelipes18 小时前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
SamDeepThinking1 天前
裁掉那个差程序员后,给你看团队里高手的代码:这个习惯,希望你有
java·后端·程序员
朕瞧着你甚好1 天前
技术雷达 & Java 集成评估报告 — Apache Tika 3.3.1
java·ai编程
MacroZheng1 天前
短短几天,暴涨2.8万Star!又一款编程神器开源!
java·人工智能·后端
SamDeepThinking1 天前
函数式编程:用BiFunction消除多类型分支的代码重复
java·后端·面试
Flittly2 天前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了2 天前
Java 生成二维码解决方案
java·后端
人活一口气2 天前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot