环境配置
建议先阅读:01_下载与安装
原理
PATH 环境变量是操作系统查找可执行文件的搜索路径列表——当输入 g++ 时,系统按 PATH 顺序在各目录中查找名为 g++ 的可执行文件。
编译过程的四个阶段:
- 预处理:展开
#include和#define,生成.i文件 - 编译:将预处理后的代码转为汇编,生成
.s文件 - 汇编:将汇编转为机器码,生成
.o目标文件 - 链接:将目标文件与库文件合并,解析符号引用,生成可执行文件
编译器选项的底层影响:
-O0禁用优化,每行 C++ 代码直译,方便单步调试-O2执行大部分优化(常量折叠、死代码消除、循环展开等),是发布版标准-g在二进制中嵌入 DWARF 调试信息(源文件映射、变量名、行号表),文件体积显著增大-fsanitize=address在编译时插入内存检查桩代码,堆/栈缓冲区溢出在运行时被捕获
建议先阅读:04_第一个程序与输入输出
语法
PATH 配置
# 查看当前 PATH (Linux/macOS)
echo $PATH
# 临时追加
export PATH="/usr/local/gcc/bin:$PATH"
# 永久配置,写入 ~/.bashrc 或 ~/.zshrc
echo 'export PATH="/usr/local/gcc/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```cpp
### 核心编译选项
| 类别 | 选项 | 作用 |
|------|------|------|
| 标准 | `-std=c++17` | 指定 C++ 标准版本 |
| 警告 | `-Wall -Wextra -Wpedantic` | 启用常见警告 |
| 优化 | `-O0` / `-O2` / `-O3` | 优化级别 |
| 调试 | `-g` | 嵌入调试信息 |
| 诊断 | `-fsanitize=address` | 运行时内存错误检测 |
| 输入/输出 | `-c` / `-o file` | 只编译 / 指定输出名 |
| 路径 | `-I dir` / `-L dir` / `-l lib` | 头文件路径 / 库路径 / 库文件 |
推荐开发期命令:
```bash
g++ -std=c++17 -Wall -Wextra -Wpedantic -g -o app main.cpp
```cpp
推荐发布期命令:
```bash
g++ -std=c++17 -O2 -DNDEBUG -o app main.cpp
```makefile
### Makefile 基础
```makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall -Wextra -g
app: main.o utils.o
$(CXX) -o $@ $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
rm -f *.o app
.PHONY: clean
```cmake
自动变量:`$@`=目标, `$<`=首个依赖, `$^`=全部依赖
### CMake 基础
```cmake
cmake_minimum_required(VERSION 3.16)
project(MyApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(myapp main.cpp utils.cpp)
```cpp
```bash
mkdir build && cd build
cmake ..
cmake --build .
```cpp
> CMake 是构建系统**生成器**,不直接编译;它生成 Makefile/Ninja 文件,再由这些工具执行编译。
### GDB 调试
| 命令 | 作用 |
|------|------|
| `break main` / `break 15` | 设置断点 |
| `run` | 启动程序 |
| `next` | 单步跳过 (不进入函数) |
| `step` | 单步进入函数 |
| `print x` | 打印变量值 |
| `backtrace` | 查看调用栈 |
| `continue` | 继续执行 |
```bash
g++ -std=c++17 -g -o app main.cpp
gdb ./app
```cpp
---
## 实践
多文件编译练习——创建 math_utils.h, math_utils.cpp, main.cpp,分别用 Makefile 和 CMake 构建。
常见编译错误速查:
| 错误信息 | 原因 | 解决 |
|----------|------|------|
| `undefined reference to 'foo()'` | 链接阶段缺符号 | 添加源文件或 `-l` 库 |
| `No such file or directory` | 找不到头文件 | `-I include_path` |
| `multiple definition of` | 重复定义 | 头文件用 `extern` 或 `inline` |
练习: 简单计算题