将源程序变为可执行程序的过程
-
高级语言---->汇编语言---->机器语言
-
更具体的变换细节
- 源代码:就是我们用C/C++写的代码,后缀名是
.c/.cpp
- 预处理器:它的作用有将我们导入的头文件展开,删除注释,替换宏等
- 预处理后源代码:就是经过预处理器处理过的代码,后缀名为
.i
它其实和第一步的源代码差不多,就是增加或替换了一些细节,还是我们可以看懂的c/c++
代码 - 编译器:它的作用就是将预处理后源代码转换为汇编代码
- 汇编代码: 就是经过编译器处理后的代码,后缀名为
.s
,这一步的代码如果有汇编基础,也可以看懂 - 汇编器: 它的作用就是将上一步的汇编代码转换为机器指令即二进制代码
- 目标代码: 就是经过汇编器处理后的代码,后缀名为
.o
,这一步的代码里面全是01的组合,基本看不懂 - 链接器: 它的作用是将目标代码与启动代码,库代码,其他目标代码(比如我们写了很多个源文件,就可以生成很多个目标代码)连接起来,组成一个完整的逻辑地址
- 可执行程序: 就是经过链接器后生成的代码,在linux中后缀名为
.out
,在window中后缀名为.exe
编译器和汇编器老是搞混,编译器是编译成汇编语言,汇编器才是编译成机器语言
- 源代码:就是我们用C/C++写的代码,后缀名是
-
在linux中常用的两种编译工具
gcc/g++
,其中gcc
常用来编译C语言程序,g++
用来编译c++语言程序。- 误区1:gcc只能编译c代码,g++只能编译c++代码(x) 其实两者都可以
- 后缀为.c的,gcc把它当作是c程序,而g++当作是c++程序
- 后缀为.cpp的,两者都会认为是c++程序,c++语法规则则更加严谨一些
- 编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和c++程序使用的库链接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接都用g++,这就给人一种错觉,好像cpp程序只能用g++
- 误区2: 编译只能用gcc,链接只能用g++
- 严格来说,这句话不算错,但是它混淆了概念,应该这样说:编译可以用gcc/g++,而链接可以用g++或者gcc -lstdc++
- gcc命令不能自动和c++程序使用的库链接,所以通常用g++来完成链接。但是在编译阶段,g++会自动调用gcc,二者等价。
- 误区3:gcc不会定义 __cplusplus 宏,而g++会
- 实际上,这个宏只标志着编译器将会把代码按C还是C++语法来解释
- 如上所述,如果后缀为.c,并且采用gcc编译器,则该宏就是未定义的,否则就是已定义的
- 误区1:gcc只能编译c代码,g++只能编译c++代码(x) 其实两者都可以
-
GCC常用参数选项
我们通常在linux中编译一个C程序的命令为
gcc test.c -o app
这句命令的作用就是将test.c源程序编译为一个可执行文件app,执行这个命令,在内部分别执行了-e,-c
命令大部分都是参考牛客网Linux系统编程https://www.nowcoder.com/study/live/504/1/8