0

0

C++怎么使用预处理器_C++宏定义教程【编译】

尼克

尼克

发布时间:2026-02-21 14:41:02

|

281人浏览过

|

来源于php中文网

原创

宏定义必须加括号防展开错误,换行用\且后无字符,避免变量声明和自增/自减;优先用constexpr替代常量宏,函数式宏改用constexpr函数;仅编译期条件、文件包含、字符串化时才需宏。

c++怎么使用预处理器_c++宏定义教程【编译】

宏定义写错括号会直接编译失败

处理器不检查语法,只做文本替换,#define 后面少个括号或漏了反斜杠,错误往往藏在展开后才暴露——比如宏里调用函数却没加括号,MAX(a, b) a > b ? a : b 这种写法在 2 * MAX(3, 4) 中会展开成 2 * 3 > 4 ? 3 : 4,结果完全不对。

  • 所有带参数的宏必须给整个表达式加括号:#define MAX(a, b) ((a) > (b) ? (a) : (b))
  • 宏体换行必须用 \,且 \ 后不能有任何字符(包括空格、注释)
  • 避免在宏里声明变量或使用自增/自减操作符,比如 INC(x) 展开为 x++,在 INC(i) + INC(i) 中行为未定义

constexpr 替代简单宏更安全

现代 C++ 里,#define PI 3.14159 这类常量宏早该淘汰了。它没有类型、不进调试符号、无法取地址,还可能被意外重定义。

  • constexpr double PI = 3.14159;,类型清晰,支持调试,还能参与模板推导
  • 函数式宏如 #define SQUARE(x) ((x) * (x)) 改成 constexpr auto square(auto x) { return x * x; }(C++20),编译期求值、类型推导、无副作用
  • 只有涉及编译期条件(#ifdef)、文件包含或字符串化(# 操作符)时,才非用宏不可

#ifdef#if defined() 行为不完全等价

看起来一样,但嵌套和逻辑组合时容易翻车。比如 #if defined(A) && !defined(B) 是合法的,而 #ifdef A && !defined(B) 直接报错。

  • #ifdef 只能单测一个标识符,不支持运算符;#if defined() 是完整表达式,可嵌套、可与 1/0 混用
  • 跨平台判断常用 #if defined(__linux__) || defined(_WIN32),不能写成多个 #ifdef 堆叠
  • #pragma once 替代 #ifndef XXX_H 头卫,更简洁,主流编译器都支持,但极端老旧环境仍需传统卫士

宏的字符串化和连接操作符很危险

# 把参数变字符串字面量,## 拼接 token,看着方便,实际极易出错:参数本身是宏时不会展开,拼接后可能产生非法标识符。

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

  • #define STR(x) #x 中,STR(__LINE__) 展开为 "__LINE__" 而不是行号字符串,要两层宏才能触发展开
  • #define CONCAT(a, b) a##b 中,CONCAT(int, _t) 得到 int_t 没问题,但 CONCAT(123, abc) 会报错:数字开头不能当标识符
  • 日志宏常用 __FILE____LINE__,务必用 STR() 包一层再套一层宏来确保展开,否则打出来的永远是字面量

宏的本质是文本替换,不是语言特性。越想让它“智能”,越容易掉进展开顺序、作用域、类型擦除的坑里。真需要灵活性,优先考虑 constexpr、模板别名或内联函数——宏只该留在编译开关、头文件卫士和极少数字符串反射场景里。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
java基础知识汇总
java基础知识汇总

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

1555

2023.10.24

typedef和define区别
typedef和define区别

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

117

2023.09.26

define的用法
define的用法

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

359

2023.10.11

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

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

1555

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

238

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

127

2025.10.17

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

826

2023.08.22

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6406

2023.09.14

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

916

2026.02.13

热门下载

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

精品课程

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

共28课时 | 4.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.6万人学习

Sass 教程
Sass 教程

共14课时 | 0.9万人学习

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

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