下面给你一份精简但系统的 C++ 预处理器(Preprocessor)总结,适合复习、面试或作为速查表。


一、什么是预处理器

  • 在编译之前执行的文本处理阶段

  • 不是 C++ 语言本身的一部分

  • 指令以 #开头,不以分号结束

#define PI 3.14
#include <iostream>

二、常用预处理指令总览

指令

作用

#define

定义宏

#undef

取消宏定义

#include

包含头文件

#if/ #elif/ #else/ #endif

条件编译

#ifdef/ #ifndef

是否定义宏

#pragma

编译器特定控制

#error

产生编译错误

#line

修改行号和文件名


三、#define宏定义

1️⃣ 无参宏

#define MAX_SIZE 100

✅ 编译前直接文本替换

❌ 无类型检查

2️⃣ 带参宏(小心副作用)

#define SQUARE(x) ((x) * (x))

⚠️ 必须加括号,否则易出错:

SQUARE(a + b)   // 错误示例

3️⃣ 多行宏

#define LOG(msg) \
    std::cout << msg << std::endl

4️⃣ 取消宏

#undef MAX_SIZE

四、#include文件包含

#include <iostream>   // 系统头文件
#include "myheader.h" // 用户头文件

📌 区别:

  • < >:标准库路径

  • " ":当前目录优先


五、条件编译(非常重要)

1️⃣ 基本用法

#if DEBUG
    std::cout << "Debug mode\n";
#endif

2️⃣ 常见组合

#ifdef _WIN32
    // Windows
#elif __linux__
    // Linux
#else
    // Other
#endif

3️⃣ 防止头文件重复包含

#ifndef MY_HEADER_H
#define MY_HEADER_H

// 头文件内容

#endif

✅ 推荐替代(非标准但广泛支持):

#pragma once

六、预定义宏(常用)

含义

__cplusplus

C++ 版本

__FILE__

当前文件名

__LINE__

当前行号

__DATE__

编译日期

__TIME__

编译时间

__func__

当前函数名

std::cout << __FILE__ << ":" << __LINE__;

七、#pragma指令

🔧 编译器相关

#pragma once          // 防止重复包含
#pragma warning(disable: 4996)
#pragma pack(push, 1) // 结构体对齐

八、#error#line

#error

#ifndef C++17
#error "C++17 required"
#endif

#line

#line 100 "main.cpp"

九、宏 vs 现代 C++

推荐替代

常量宏

constexpr

函数宏

inline/ 模板

类型宏

using/ typedef

现代 C++ 建议:尽量少用宏


十、预处理流程示意

源码 → 预处理器 → 编译 → 汇编 → 链接
        ↑
    宏展开、头文件展开

查看预处理结果:

g++ -E main.cpp

十一、常见坑 ⚠️

  1. 宏没有作用域

  2. 宏参数多次求值

  3. 调试困难

  4. 优先级错误(缺括号)

  5. ++--结合时产生副作用


十二、一句话总结

预处理器是“文本替换工具”,不是真正的 C++ 代码;能用现代 C++ 特性就不要用宏。


更多推荐