讲师中心 微信公众号
AI工具推荐 视频效率加速

C++宏定义中的井号#和双井号##怎么用

冬宇吖_6794

冬宇吖_6794

发布时间:2026-10-01 14:25:36

|

996人浏览过

|

来源于php中文网

原创

将宏参数转为带双引号的字符串字面量,不展开;##将两记号拼接成新标识符;二者需配合间接宏处理内置宏或嵌套展开,且须注意空参数、非法标识符及展开顺序。

c++宏定义中的井号#和双井号##怎么用

宏里加#号:把参数变成字符串字面量

预处理器遇到 # 会把紧随其后的宏参数原样转成带双引号的字符串,不展开、不计算。比如写日志或调试时想打印变量名本身,而不是它的值,就得靠它。

常见错误是以为 # 能展开嵌套宏——它不能。如果参数本身是另一个宏,# 只包住那个宏名,不是它展开后的结果。

  • LOG(x) 定义为 #define LOG(x) printf("value of " #x " is %d\n", x),调用 LOG(i) 输出 value of i is 42
  • 但若 VAL 是个宏 #define VAL 100,LOG(VAL) 打印的是 value of VAL is 100,不是 value of 100 is 100
  • 要先展开再字符串化,得套一层间接宏:#define STR(x) #x 和 #define XSTR(x) STR(x),然后用 XSTR(VAL) 得到 "100"

宏里用##:拼接两个记号成一个新标识符

## 是“记号粘合器”,把左右两边预处理后的记号(token)强行拼成一个。常用于生成变量名、函数名或类型名,比如按版本或配置生成不同后缀的函数。

最容易踩的坑是拼出来的东西不是合法标识符——比如前后都是空、中间有空格、拼出数字开头的名字,或者拼完后刚好是关键字(如拼出 int_t 但 int 是关键字),预处理器不报错,但编译器会报错。

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

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • CONCAT(a, b) 定义为 #define CONCAT(a, b) a##b,CONCAT(foo, _v1) 展开为 foo_v1
  • 不能写 CONCAT(int, _t),因为 int_t 合法,但 CONCAT(123, abc) 拼出 123abc,非法标识符
  • 参数为空时可能意外拼出奇怪东西,比如 CONCAT(x, ) 变成 x(空参数被忽略),但 CONCAT(, y) 会报错:前置空 token 不允许

实际组合用法:带调试信息的断言宏

真实项目里 # 和 ## 经常一起出现,典型例子是自定义 assert:既要打印表达式原文(用 #),又要生成唯一错误处理函数名(用 ##)。

注意行号和文件名这类内置宏(__LINE__、__FILE__)必须通过间接宏才能进 # 或 ##,否则它们会被当字面量处理,而不是展开成数字或字符串。

  • 直接写 #__LINE__ 得到 "__LINE__";要得到 "123",得用 #define STRINGIFY(x) #x + STRINGIFY(__LINE__)
  • 生成函数名如 assert_fail_123:先用 ## 拼 assert_fail_##__LINE__,但需两层宏绕过 __LINE__ 的延迟展开
  • 完整套路:#define ASSERT(x) do { if (!(x)) assert_fail_impl(__FILE__, __LINE__, #x); } while(0) —— 这里 #x 记录条件,__FILE__ 和 __LINE__ 传给函数,不参与拼接

宏展开顺序和括号陷阱

# 和 ## 在宏体中优先级最高,但整个宏参数先做一次展开(除非被 # 或 ## 阻止),再执行字符串化或拼接。这个顺序决定了你能不能拿到想要的结果。

最隐蔽的问题是忘记给宏参数加括号——尤其在 ## 左右有运算符时,比如 ADD(x, y) 定义为 #define ADD(x, y) x##+##y,调用 ADD(1, 2) 会试图拼出 1+2,这不是合法标识符,编译失败。而 # 不吃括号, #(x+y) 会变成 "(x+y)",但如果你本意是先算再转字符串,宏做不到。

  • 参数含逗号时,必须用括号包裹整个参数,否则预处理器按逗号分隔参数,比如 MACRO((a, b), c) 中第一个参数才是 (a, b)
  • ## 两端不能是预处理关键字(如 ##include)、字符串字面量或注释
  • 标准不保证 ## 拼接后是否重新扫描,所以别指望拼出的新记号能自动触发下一轮宏展开

宏里的 # 和 ## 看似简单,但一旦涉及多层展开、空参数、内置宏或非法拼接,错误往往只在编译时报出来,且提示位置指向展开后的代码,不是原始宏定义。动手前先想清楚:这里到底需要字面量,还是真要拼标识符;参数会不会为空;拼出来的东西编译器认不认识。

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2208

2024.03.14

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

979

2024.03.14

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

407

2024.03.14

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

307

2024.03.14

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

386

2024.03.14

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

580

2024.03.14

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

1389

2024.03.21

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

1197

2024.03.22

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

0

2026.09.30

热门下载

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

精品课程

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

共115课时 | 42.4万人学习

c语言项目php解释器源码分析探索
c语言项目php解释器源码分析探索

共7课时 | 0.5万人学习

nginx浅谈
nginx浅谈

共15课时 | 1.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn