c语言代码的编译和链接过程

代码编译过程

1. 程序的编译过程(gcc编译器)

1.1 预处理

gcc -E hello.c -o hello.i

-E 表示预处理,-o表示指定输出文件。

预处理的过程就是将 # 开头的代码进行处理,并且处理空行和注释。
(1)头文件#include <>的处理
在预处理阶段仅仅是将头文件包含进来,放置到.c或者.cpp文件中,不会对语法进行检查,就算语法有错误也不会报错,第二个阶段(编译)才检查语法

头文件说明:
#include< >: 用尖括号包含的文件,编译器会从系统指定路径下找头文件。
#include" " : 用双引号包含的文件,编译器会先从当前目录下查找头文件,如果没找到,再从系统指定路径下找头文件。
include常用来包含头文件,也可以包含.c文件,但不要多次包含,因为预处理阶段是将包含的文件在.c或者.cpp文件中进行展开,如果多次包含,则会在编译阶段报错多次定义(声明可以多次声明,但是定义不能,static定义的静态变量除外,因为静态变量存放在全局区,只会被定义一次)

(2)宏定义处理
在预处理阶段,会将所有宏进行展开。

宏定义说明:
宏定义的作用范围从定义开始直到本文件末尾,如果要终止宏定义的话,使用#undef 宏名
带参宏和带参函数的区别:带参宏被调用多少次就展开多少次,执行的时候没有代码调用的过程,浪费了空间和编译时间,但是节省了运行时间;且带参宏的形参是没有类型的。带参函数的代码只有一份,存放在代码区(代码区保存cpu执行的指令,即代码汇编形成的二进制代码,代码区的内容一般是只读和共享的,只读是为了方式在程序运行时改变了cpu指令),调用的时候有一个指针跳转的过程,栈区将下一行代码的地址压入栈内,再将函数的参数压入栈内,指针指向函数入口地址,执行完函数之后将参数弹出栈,将下一行代码地址弹出栈,还原现场,继续执行代码,这个过程浪费了运行时间,但是节省了空间和编译时间;且带参函数的形参是有类型的。
因此可以看到,在linux内核文件中大量使用了宏定义,这样是为了牺牲内核的编译时间来换取系统运行的高效率;而在应用程序中则使用函数较宏多,这是为了保证程序的稳定性。

1.2 编译

gcc -S hello.i -o hello.s 

-S代表编译

编译解决的问题就是将预处理好的代码翻译为汇编语言。

1.3 汇编

gcc -c hello.s -o hello.o

-c 表示执行汇编,.o代表obj目标文件,在clang编译器下是.obj后缀。可以使用objdump -s -d hello.o 查看该字节码文件

使用汇编器将汇编代码翻译成机器语言,但是这个机器语言还不能执行,因为在预处理过程中仅仅只是把头文件包含进了程序文件中,但是相对应的实现代码没有包含进来,所以这个字节码文件还不是最终的产品。

2. 程序的链接过程

gcc hello.o -o hello

链接阶段使用链接器执行,预处理中有些系统头文件的实现没有包含进来,那么在这一步就需要将需要的文件包含进来了,直接使用gcc hello.o –o hello即可得到最终的可执行文件。

如果使用静态库,那么在这一步链接器就会将静态库和本项目的字节码文件一起打包生成最终的可执行文件,如果使用动态库,那么在这一步也有处理,但是不会将动态库一起打包,而是在运行的时候才动态加载。这两种库开发中都会用到,一般使用其它库都需要首先引入头文件,为什么?和第一步预处理有关,首先有头文件声明才能进行参与编译过程,而库文件一般都是代表实现头文件的代码生成的字节码文件。

先将#inclde相对应的cpp程序文件编译成.o目标文件,当链接选项将其打包成静态库文件时,与项目.o文件一同生成可执行二进制文件。如果使用动态库,那么在这一步也有处理,但是不会将动态库一起打包,而是在运行的时候才动态加载

静态链接和动态链接的区别
动态链接:当程序调用到库文件时,从库文件中寻找,而不是直接把库中的代码直接加载到可执行文件中。
静态链接:将库文件都加载到可执行文件中,与之前生成的.o文件已经无关了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值