0

0

C++ 宏定义和const区别 C++ 预处理替换与编译期类型检查【理论】

尼克

尼克

发布时间:2026-01-30 15:21:25

|

623人浏览过

|

来源于php中文网

原创

宏定义在预处理阶段纯文本替换,无类型、无作用域、不参与编译检查;const变量具类型和地址,可调试;constexpr是现代C++推荐的编译期常量方案,类型安全且支持编译期计算。

c++ 宏定义和const区别 c++ 预处理替换与编译期类型检查【理论】

宏定义在预处理阶段就被替换了,根本没机会参与类型检查

处理器只做纯文本替换,#define PI 3.14159 后,所有 PI 都被无差别替换成 3.14159,连括号都不加。它不占内存、没有作用域、不经过编译器语义分析——所以 sizeof(PI) 是非法的(预处理后变成 sizeof(3.14159),但这是字面量,不是对象),而 auto x = PI; 中的 x 类型由字面量推导为 double,但这个过程发生在替换之后,和宏本身无关。

常见错误现象:

  • #define MAX(a,b) a > b ? a : b 导致 MAX(i++, j++) 展开成 i++ > j++ ? i++ : j++,副作用执行两次
  • #define FLAG 1int FLAG = 2; 在同一作用域不报错(宏先被删了),但逻辑混乱
  • 调试时无法对宏名设断点,IDE 里看不到“变量”定义位置

const 变量是真正的编译期常量(满足条件时),有类型、有地址、能进符号表

const double PI = 3.14159; 声明了一个具有 double 类型的左值,有内存地址(除非被优化掉),支持取址 &PI,可参与模板推导、用作数组维度(若为字面量常量表达式)、能出现在 switchcase 中(前提是是 constexpr 或整型字面量常量表达式)。

但注意:不是所有 const 都是编译期常量:

立即学习C++免费学习笔记(深入)”;

PpcyAI
PpcyAI

泡泡次元AI-游戏美术AI创作平台,低门槛上手,高度可控,让你的创意秒速落地

下载
  • const int x = rand(); —— 运行期初始化,只是不可修改,不能用于模板非类型参数
  • const int y = 42; —— 满足常量表达式要求,等价于 constexpr int y = 42;(C++17 起隐式 constexpr)
  • extern const int z; —— 外部链接,定义在别处,编译器通常无法在本翻译单元确认其值,不能用于需要常量表达式的地方

用 constexpr 替代宏才是现代 C++ 的正确姿势

宏该退场了。真正需要编译期常量的地方,优先用 constexpr

  • constexpr double PI = 3.1415926535; —— 类型安全、可调试、支持 sizeof、能用于所有常量表达式上下文
  • constexpr int square(int x) { return x * x; } —— 函数也能编译期求值,宏函数做不到泛型和重载
  • template struct Array { int data[N]; }; —— 模板参数必须是常量表达式,Array 错(PIdouble),但 Array 对(返回 int

宏只剩少数场景还必要:条件编译(#ifdef)、头文件卫士(#pragma once#ifndef XXX_H)、字符串化(#__FILE__)、连接符(###)——这些是预处理器专属能力,constexpr 无法替代。

调试和符号信息差异直接影响开发体验

你用 gdb 调试时,print PI 会提示 “no symbol”,因为宏早已消失;而 print PI_const(对应 const double PI_const = ...)能正常显示值、类型、地址。IDE 的跳转、重命名、查找引用等功能对宏完全失效,但对 constconstexpr 变量完全支持。

容易被忽略的一点:const 变量默认内部链接(static),而宏没有链接属性概念——这意味着多个源文件里定义同名 const int x = 1; 不会链接冲突,但宏定义重复可能导致意外覆盖或警告。反过来,如果真需要外部链接的编译期常量,得显式写 extern constexpr int x = 1; 并在某处定义。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.09.27

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

109

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

338

2023.10.11

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

540

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

423

2024.03.13

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

531

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

319

2023.08.03

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

Sass 教程
Sass 教程

共14课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号