C++ #define 预处理器完全解析
#define` 是 C++ 预处理指令(不是 C++ 语言本身的语法),在编译之前由预处理器执行,核心作用是:文本替换 + 定义宏。
它的处理时机:
- 源代码 → 预处理器(执行
#define替换)→ 编译器 → 可执行程序 - 替换是纯文本无脑替换,没有类型检查、没有语法检查
一、基础用法:定义常量
最常用的场景:用名字代替固定数值,方便修改和阅读。
#include <iostream>
// 定义:PI 等价于 3.14159
#define PI 3.14159
int main() {
// 预处理后会变成:double r = 2 * 3.14159;
double r = 2 * PI;
std::cout << r << std::endl;
return 0;
}注意
- 定义末尾不要加分号,否则分号会被一起替换,导致编译错误。
- C++ 更推荐用
const定义常量(有类型检查、有作用域),#define是纯文本替换。
二、进阶用法:带参数的宏(宏函数)
可以像函数一样传参,但本质还是文本替换,不是真正的函数。
#include <iostream>
// 定义求平方的宏
#define SQUARE(x) x*x
int main() {
// 预处理后:int a = 3*3;
int a = SQUARE(3);
std::cout << a << std::endl; // 输出 9
return 0;
}⚠️ 宏的经典陷阱(必须掌握)
纯文本替换会出意外,看这个例子:
#define SQUARE(x) x*x int a = SQUARE(3+1); // 预处理后:3+1*3+1 = 3+3+1 = 7(不是期望的 16!)
修复方案:给参数和整体加括号
#define SQUARE(x) ((x)*(x)) int a = SQUARE(3+1); // 预处理后:((3+1)*(3+1)) = 16(正确)
三、高级用法:条件编译(常用)
#define 配合 #ifdef / #ifndef / #endif,可以选择性编译代码,这是工程中最核心的用途。
1. 判断宏是否定义
#define DEBUG
int main() {
// 如果定义了 DEBUG 宏,就编译这段代码
#ifdef DEBUG
std::cout << "调试模式开启" << std::endl;
#else
std::cout << "发布模式" << std::endl;
#endif
return 0;
}2. 防止头文件重复包含(最重要)
每个头文件开头都要写,避免重复定义错误:
// 防止该头文件被多次包含 #ifndef _MY_HEADER_H_ #define _MY_HEADER_H_ // 你的代码:函数声明、类定义等 #endif // 结束判断
C++11 后也可以用 #pragma once,更简洁,但 #ifndef 兼容性更好。
四、取消宏定义:#undef
可以手动取消已定义的宏:
#define NUM 100 #undef NUM // 取消 NUM 宏 // 下面再用 NUM 会报错:未定义
五、#define 优缺点总结
✅ 优点
- 编译前替换,无函数调用开销(适合简单计算)
- 可以做条件编译、头文件保护
- 代码更易读、易维护
❌ 缺点(C++ 不推荐滥用)
- 纯文本替换,无类型检查、无作用域、容易出bug
- 调试困难(看不到宏展开后的代码)
- 复杂宏可读性极差
C++ 推荐替代方案
- 常量:用
const/constexpr代替#define - 函数:用
inline内联函数代替宏函数 - 头文件保护:
#pragma once或#ifndef
总结
#define是预处理指令,做纯文本替换- 两种用法:定义常量、带参宏函数
- 宏函数必须加括号避免陷阱
- 核心工程用途:条件编译 + 头文件防重复包含
- C++ 中尽量少用,优先用
const/inline替代
到此这篇关于C++ #define 预处理器 完全讲解的文章就介绍到这了,更多相关C++ #define 预处理器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)
这篇文章主要介绍了C#使用Socket实现服务器与多个客户端通信(简单的聊天系统),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-02-02
WinForm中DefWndProc、WndProc与IMessageFilter的区别
这篇文章主要介绍了WinForm中DefWndProc、WndProc与IMessageFilter的区别,较为详细的分析了WinForm的消息处理机制,需要的朋友可以参考下2014-08-08
C#中的enum、struct和class三种类型的对比总结
在 C# 类型系统中,enum、struct 和 class 是三种最基础且最重要的类型定义方式,本文将系统性地总结这三种类型的特性、差异及使用建议,希望对大家有所帮助2026-03-03


最新评论