1. C++的编译过程
使用 g++
等编译工具,从源码生成最终的可执行文件一般有这几步:预处理(Preprocess)、编译(Compile)、汇编(assemble)、链接(link)。
举例:
int main(int argc, char** argv)
首先来看 char*是什么?
🌟 简单回答:
✅
char*
本质上是一个地址,指向一块连续的字符内存。✅ 如果这块内存的末尾有一个
'\0'
,我们就把它当作字符串来处理
再来看 char** 是什么
言归正传。在进行 命令行输入时,输入 g++ --help
可以看到对应命令:
-E Preprocess only; do not compile, assemble or link.
-S Compile only; do not assemble or link.
-c Compile and assemble, but do not link.
-o <file> Place the output into <file>.
-
第一步:预处理
C++ 中预处理指令以#
开头。在预处理阶段,会对#define
进行宏展开,处理#if,#else
等条件编译指令,递归处理#include
。这一步需要我们添加所有头文件的引用路径。# 将xx.cpp源文件预处理成xx.i文件(文本文件) g++ -E main.cpp -o main.i
-
第二步:编译
检查代码的规范性和语法错误等,检查完毕后把代码翻译成汇编语言文件。
# 将xx.i文件编译为xx.s的汇编文件(文本文件) g++ -S main.i -o main.s
-
第三步:汇编
基于汇编语言文件生成二进制格式的目标文件。# 将xx.s文件汇编成xx.o的二进制目标文件 g++ -c main.s -o main.o
-
第四步:链接
-
将目标代码与所依赖的库文件进行关联或者组装,合成一个可执行文件
# 将xx.o二进制文件进行链接,最终生成可执行程序 g++ main.o -o main
2. 静态链接库和动态链接库
主要是在链接的阶段不一样
-
静态链接库名称一般是
lib库名称.a
(.a
代表archive library
),其链接发生在编译环节。一个工程如果依赖一个静态链接库,其输出的库或可执行文件会将静态链接库*.a
打包到该工程的输出文件中(可执行文件或库),因此生成的文件比较大,但在运行时也就不再需要库文件了。 -
而动态链接库的链接发生在程序的执行过程中,其在编译环节仅执行链接检查,而不进行真正的链接,这样可以节省系统的开销。动态库一般后缀名为
*.so
(.so
代表shared object
,Linux:lib库名称.so
,macOS:lib库名称.dylib
)。动态链接库加载后,在内存中仅保存一份拷贝,多个程序依赖它时,不会重复加载和拷贝,这样也节省了内存的空间
3. 什么是Cmake?
🧩 CMake 是什么?(因为大量的第三方库需要进行编译)
✅ CMake 是一个跨平台的自动化构建工具,用来生成编译项目所需的文件(例如 Makefile 或 Visual Studio 工程文件)
C++是一门十分底层的语言,
✅ 计算机只懂“机器码(二进制)”,而我们写的是“人类能读的 C++ 代码”。编译的目的就是把 C++ 代码翻译成计算机能运行的机器语言。
我用中文 向老外 要一元钱:
类比 | 实际编程中 |
---|---|
你写中文 | 你写 C++ 源代码 |
翻译人员 | 编译器(如 g++ 或 clang) |
老外读英文的过程 | CPU 只能执行机器码(二进制) |
给我一元钱 | 执行 编译成 .exe 或 .out 的可执行文件,输出 |
4. Cmake项目的构建构成