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. 字符串常量存放在只读数据区,禁止通过指针修改内容。
相关推荐
object not found1 小时前
Node.js fs 常用 API 整理:node:fs/promises、node:fs、fs 到底怎么用
开发语言·前端·javascript
江屿风1 小时前
C++图论基础拓扑排序经典OJ题流食般投喂
开发语言·c++·笔记·算法·图论
芯岭技术郦1 小时前
MS32C001‑C:极致成本 32 位 MCU
c语言·开发语言·单片机
程序员小羊!1 小时前
17 Maven
java·maven
C+-C资深大佬1 小时前
C++ 数字与字符串互转
java·c++·算法
nexustech1 小时前
simplejson:Python JSON 处理的备用引擎
开发语言·python·其他·json
陈猪的杰咪1 小时前
DeepSeek V4 中转方案全解析 | Flash 成本仅为 GPT 的 1/90
java·人工智能·gpt·spring
zlpzlpzyd1 小时前
spring boot 4.1发布
java·数据库·spring boot
雷工笔记1 小时前
MES系列48-MES 系统「质量管理」完整设计与实施方案
开发语言·javascript·ecmascript