应使用 const int 而非 #define 定义整型常量,因其具备类型安全、作用域控制、可调试、可取地址等优势;必要时用 constexpr 保证编译期常量表达式。

用 const int 定义整型常量才是现代 C++ 的标准做法
直接说结论:别用 #define 定义 int 常量,优先写 const int MAX_SIZE = 100;。这不是风格偏好,而是类型安全、作用域控制和调试友好的刚性需求。
#define 替换发生在预处理阶段,根本没类型这回事
预处理器只做文本替换,不经过编译器检查。比如:
#define PI 3.14159 #define BUFFER_SIZE 1024
问题来了:
-
PI在调试器里看不到——它压根不是变量,只是个被替换了的数字字符串 - 如果写
int x = PI + "hello";,错误会出现在使用处,而不是定义处;编译器报错时显示的是3.14159 + "hello",毫无上下文 - 宏没有作用域,
BUFFER_SIZE可能在头文件里污染整个翻译单元,和你自己的变量名冲突也不报错 - 不能取地址:
&BUFFER_SIZE直接编译失败
const int 是真正的变量,有类型、有作用域、能调试
它参与编译全过程,编译器知道它是 int,知道它在哪个作用域,也知道它不可修改:
立即学习“C++免费学习笔记(深入)”;
const int MAX_CONNECTIONS = 64; static const int DEFAULT_TIMEOUT = 5000; // 加 static 限定内部链接,避免 ODR 违规
关键点:
- 必须初始化,否则编译报错:
const int x;❌ - 在函数内定义是局部常量;在命名空间作用域定义默认有内部链接(C++17 起),加
extern才可跨文件使用 - 可以取地址、传引用、用于模板非类型参数(C++20 起支持
constexpr更稳妥) - 调试时断点停在
MAX_CONNECTIONS上,能看到值和类型
真要“宏级”替换?用 constexpr int,不是 #define
如果需要在编译期求值、做数组大小、模板参数等,const int 在某些旧编译器或复杂场景下可能不够(比如未被识别为常量表达式),这时该上 constexpr:
constexpr int ARRAY_SIZE = 256; int arr[ARRAY_SIZE]; // 合法,且 arr 大小在编译期确定
注意:
-
constexpr比const要求更严:必须能编译期计算,且初始化表达式必须是常量表达式 - 不需要显式写
const,constexpr已隐含const - 不要为了“看起来像宏”而硬套
constexpr——普通常量就用const int,够用又清晰
最容易被忽略的一点:头文件里大量用 #define 定义数值常量,看似省事,实则让 IDE 补全失效、静态分析绕过、重构工具失灵。哪怕只是临时改个名字,const int 都能靠重命名功能全局更新,#define 只能全文本搜索替换——还容易误伤注释或字符串里的相同数字。









