1.4 C/C++ 预处理
一、什么是预处理?预处理在编译的哪个阶段?
预处理是 C/C++ 编译过程的第一个阶段,它发生在正式编译(词法分析、语法分析、代码生成)之前。
预处理器是一个文本处理程序,它根据源文件中以 # 开头的预处理指令,对源代码进行文本替换、文件嵌入和条件筛选等操作。
- 编译流程:预处理 → 编译 → 汇编 → 链接
┌─────────────┐
│ 源文件 │ main.c / main.cpp
│ *.c/*.cpp │
└──────┬──────┘
↓
┌─────────────┐
│ 预处理器 │ 处理 #include、#define、#ifdef 等
│ 预处理阶段 │ 生成展开后的文本
└──────┬──────┘
↓
┌─────────────┐
│ 编译器 │ 词法分析 → 语法分析 → 语义分析
│ 编译阶段 │ 中间代码生成 → 优化
└──────┬──────┘
↓
┌─────────────┐
│ 汇编器 │ 生成机器码
│ 汇编阶段 │ 输出 *.o / *.obj 目标文件
└──────┬──────┘
↓
┌─────────────┐
│ 链接器 │ 链接库文件、合并目标文件
│ 链接阶段 │ 输出可执行文件 *.exe / a.out
└─────────────┘
二、预处理主要做什么?
- 文件包含(
#include):将指定文件的内容原样插入到当前文件中。 - 宏定义与替换(
#define):将定义的符号常量或宏函数进行文本替换。 - 条件编译(
#ifdef、#if等):根据条件决定哪些代码参与编译,哪些被剔除。 - 特殊指令(
#pragma、#error等)。 - 注释在预处理阶段被移除。
预处理指令汇总表:
指令 |
功能 |
示例 |
|
文件包含 |
|
|
宏定义 |
|
|
取消宏 |
|
|
如果宏已定义 |
|
|
如果宏未定义 |
|
|
条件判断 |
|
|
否则如果 |
|
|
否则 |
|
|
结束条件 |
|
|
编译器指令 |
|
|
编译错误 |
|
|
修改行号 |
|
|
字符串化 |
|
|
连接 |
|
三、#define 和 const 有什么区别?
#define 是预处理阶段的文本替换,无类型检查和作用域;const 是编译阶段的类型安全常量,有作用域且可调试。
对比 |
#define |
const |
处理阶段 |
预处理 |
编译 |
类型检查 |
❌ 无 |
✅ 有 |
作用域 |
无限制 |
遵循作用域 |
内存占用 |
多次替换 |
只有一份 |
调试 |
❌ 不可调试 |
✅ 可调试 |
用途 |
条件编译、宏函数 |
类型安全的常量 |
四、头文件为什么要加 #ifndef / #de
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
C++/嵌入式开发 秋招面经 文章被收录于专栏
一名985硕,在25年秋招中斩获多个C++/嵌入式开发Offer。本专栏将分享我的面经,涵盖C/C++、操作系统、计算机网络、ARM体系与架构、Linux应用/驱动开发、Qt、通信协议及开发工具链等核心内容。
查看12道真题和解析