c程序编译链接的过程解析

前言

c程序编译过程有的人会直接简述成四个字:编译链接
但我们知道对于任何一个c程序而言从.c/.cpp文件到最后的.exe/a.out可执行文件,期间都经历了四个步骤

从.c/.cpp到.exe/a.out的四个步骤

1.预处理

问1:预处理要处理什么内容?
答1:1.头文件,2.宏定义:#define,
1.头文件

而头文件里的存放什么呢?
有这么三样
1.函数原型声明
2.全局变量的声明
3.定义的宏和类型
4.全局常量
5.库函数

2.宏定义:#define
例1:#define PI 3.14159

就是定义了一个常量的宏PI,而在预处理过程中就是要将程序中的PI替换成3.14159。

例2:#define F(x) x*x

就是定义了一个表达式的宏F(x),而在预处理过程中就是要将程序中的F(x)替换成x*x。

2.汇编(编译器工作)

编译器将预处理后的C代码转换成汇编代码。这一步生成的代码是特定于目标机器的汇编语言,但仍然是文本形式。这种代码是低级语言,接近机器码,但仍然是人类可读的形式。
这种形式的文本可以用gcc -S filename.c生成出来,再用文本编辑器查看

3.编译(汇编器工作)

汇编器将汇编代码转换成机器代码。这个过程涉及到将汇编指令转换成二进制形式的机器指令,并将它们存储在目标代码文件中。这个过程也包括了代码优化,以提高程序的执行效率。

问2:编译阶段要处理什么呢?
答2:类型别名:typedef(type alias)
类型别名:typedef(type alias)

例如:为结构体起别名:
typedef struct {
int x;
int y;
} Point;
又有typedef long int;
这种编写方式可以在不用改变代码习惯的前提下就将32b的数据,扩充到了64b
而这种别名int在预处理就会被替换成long进行下一步的汇编
然而在Ubuntu的GNU编译器上我发现long int本身就是一个数据类型,包括long,long long int这三个数据类型所占内存都是8B
在这里插入图片描述

在这里插入图片描述

4.链接(链接程序工作)

链接在范围上可以分为外部链接和内部链接。
对于变量而言,如果不声明extern,那么变量默认就是局部的
对于函数而言,如果不声明static,那么函数的链接性就是全局的
(在很多编译器中对于一个自动生成的main函数,是不是默认就用static修饰呢?)
链接程序将一个或多个目标代码文件,以及可能需要的库文件,链接在一起生成最终的可执行文件。链接器解决代码中的外部引用,确保所有的函数和变量都能正确地被定位。

链接程序将需要确定地址的符号(包含变量和函数)记录下来。通过完整的地址就可以将所需要的符号连接在一起生成可执行文件。

注:链接器不仅解决外部引用,还负责合并代码和数据,以及处理符号冲突等问题。

注:诸位站友如有所收获不如点个免费的赞,如有错误之处或有其它补充的点,请在评论区发表你的观点,看到必回。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值