C++基础——编译篇
🔧 一、C++ 编译过程概述
C++ 的编译过程可以分为以下几个阶段:
- 预处理(Preprocessing)
- 编译(Compilation)
- 汇编(Assembly)
- 链接(Linking)
这些步骤共同将源代码(.cpp
)变成可执行文件(.exe
、.out
等)。
📌 示例文件:
// main.cpp
#include <iostream>
int add(int a, int b) {
return a + b;
}
int main() {
std::cout << add(3, 4) << std::endl;
return 0;
}
🧩 1. 预处理(Preprocessing)
输入:源代码(.cpp)
输出:预处理后的代码(.i)
预处理器会处理以下内容:
#include
:插入头文件内容#define
:宏定义替换- 条件编译指令:
#ifdef
,#ifndef
,#endif
命令行演示(GCC):
g++ -E main.cpp -o main.i
⚙️ 2. 编译(Compilation)
输入:预处理后的代码(.i)
输出:汇编代码(.s)
编译器将源代码翻译成 汇编语言,并做词法分析、语法分析、语义分析、优化等。
命令行演示:
g++ -S main.i -o main.s
🛠️ 3. 汇编(Assembly)
输入:汇编代码(.s)
输出:目标文件(.o 或 .obj)
汇编器(Assembler)把汇编代码翻译成 机器代码(二进制),但还不能运行。
g++ -c main.s -o main.o
🔗 4. 链接(Linking)
输入:一个或多个目标文件(.o)和库文件
输出:可执行文件(.exe, .out)
链接器把所有目标文件和需要的库整合成一个可执行程序。
g++ main.o -o main
如果使用了标准库或者第三方库(如
libm.so
),链接器还会处理符号解析、地址修正等。
🧠 编译过程中涉及的重要概念
1. 头文件和源文件
.h
/.hpp
:声明类、函数、宏等.cpp
:定义函数、类等实现内容- 使用
#include
包含头文件
2. 宏定义与条件编译
#define PI 3.14
#ifdef DEBUG
std::cout << "Debug mode" << std::endl;
#endif
3. 多文件编译
// add.h
int add(int a, int b);
// add.cpp
int add(int a, int b) {
return a + b;
}
// main.cpp
#include <iostream>
#include "add.h"
int main() {
std::cout << add(1, 2) << std::endl;
}
编译:
g++ -c add.cpp -o add.o
g++ -c main.cpp -o main.o
g++ add.o main.o -o app
📚 编译相关工具和选项
工具/选项 | 说明 |
---|---|
g++ |
GNU 编译器,常用来编译 C++ 程序 |
-E |
只执行预处理阶段 |
-S |
编译为汇编代码 |
-c |
编译但不链接,生成 .o |
-o |
指定输出文件名 |
-I |
添加头文件搜索路径 |
-L |
添加库文件搜索路径 |
-l<name> |
链接库,例如 -lm 表示链接 libm.so |
-Wall |
开启所有常用警告 |
-g |
添加调试信息 |
-O2 , -O3 |
编译优化等级 |
-std=c++17 |
指定 C++ 版本标准 |
🧾 依赖关系和 Makefile(自动化构建)
简单 Makefile 示例:
app: main.o add.o
g++ main.o add.o -o app
main.o: main.cpp add.h
g++ -c main.cpp
add.o: add.cpp add.h
g++ -c add.cpp
clean:
rm -f *.o app
使用:
make
make clean
✅ 总结:编译流程图
main.cpp
│
▼
[ 预处理 ] ──> main.i
│
▼
[ 编译 ] ───> main.s
│
▼
[ 汇编 ] ───> main.o
│
▼
[ 链接 ] ───> 可执行文件 (main / main.exe)