小解C语言文件编译过程【linux】

看到标题是文件编译过程
但是开头却是库,这可不是挂羊头卖狗肉,而是因为库也是代码不可缺少的一部分并且在编译过程中需要进行处理

那我们首先需要知道什么是库?

还记得我们写C语言时候,如果用到printf等函数,需要包上stdio的头文件吗
包上头文件后我们就能正常使用函数了
但是实际上,头文件中,只有函数的声明,而没有函数的实现和定义

那实现代码在哪呢?
就是在库中。

但是我们在写代码的过程中,并没有导入库
而导入库就是编译的过程中的部分了。

现在先来讲库的种类。

动态库

linux
动态库 .so
win
动态库:.dll

静态库

linux:
静态库 .a
windows
静态库:.lib

库的类型区分,主要体现在导入的方法中。

所以接下来进入编译过程的解读。

C语言文件 程序编译过程

大家都知道,对于计算机来说,只认识二进制码
那我们用了这么久的C语言,大家可能对C语言是如何转化成机器语言优点不太熟悉
所以这里就用linux系统,来带大家来认识一下C程序的编译过程

这里为了讲解就随便用了一个写了一个.C文件

#include<stdio.h>
#define max 10
int main()
{
  printf("%d\n",max);
  return 0;
}

整体

大致流程如图
在这里插入图片描述
接下来我们分别来看一下每个步骤:

预处理

预处理主要是将程序中的头文件展开以及宏定义和特殊符号进行处理

在linux中我们可以用

gcc -E test.c -o test.i

进行执行

这里的-E代表的意思是执行预处理指令
预处理结束后,会生成.i的文件
但是这里为了方便就直接重命名成test.i了
在这里插入图片描述
这里多了test.i文件
在这里插入图片描述
在test.i文件内部,我们能发现已经将stdio的头文件进行了展开
在这里插入图片描述
我们的写的代码还未进行处理

编译

编译:检查C语言程序语法,并将其转化为汇编语言。
可以用:

gcc -S test.i -o test.s

这个指令是要求test.c文件执行编译步骤

结束后会生成.s文件

在这里插入图片描述
我们通过cat指令
能看到test.c内部是汇编语言

汇编

汇编:将汇编语言转化为二进制码

通过一下代码执行至汇编部分

gcc -c test.s -o test.o

但是将代码转化为计算机认识的二进制码以后,也还没结束
还有最后一步。

链接

链接:将二进制码与程序所需的库相链接

库已经在上面进行了解释

gcc test.o -o test

这里就是最后一步了,成功生成了test的可执行程序

但是其实,链接还有两种情况,记得我们上面讲的静态库和动态库

链接的作用是将库和文件链接
那既然有两种库,那就有两种链接方式。

动态链接

动态链接就是链接动态库
动态库链接方式其实就是我们上面的

gcc test.o -o test

就是说默认的链接方式就是动态链接

那动态链接是如何使用库的呢?
通俗的讲就是:需要用到库的时候自己去库里面找

留下了函数对应的接口,之后需要使用库的内容的时候,直接去原库中去寻找。

静态链接

静态链接是与静态库相对应的
当我们使用静态库的时候就进行静态链接。
我们可以用

gcc test.o -static -o test

这个方式来设置为静态链接
我们可以看看静态链接和动态链接文件大小

在这里插入图片描述

我们看到动态和静态大小差异巨大
这是因为:静态链接方式是将整个静态库写入至代码中

可以说这多出来的800000位的大小都是库的大小

两种方法对比

了解两种的链接方式后,会发现他们其实优缺点还是挺明显的

静态链接
优点:方便移植,不需要搭建库(毕竟整个库都在文件中)
缺点:浪费资源(读写资源,磁盘空间等)
静态链接
优点:节省资源
缺点:使用时需要下载动态库

但是实际上使用的时候,可以在一个项目中按照需求进行选择
做到静态和动态链接搭配使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想学c啊啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值