C/C++编译过程学习记录

  说来惭愧,我是一个二本院校的软件工程专业毕业的学生,到现在仿佛什么都还不会。对于大一下学期学的C语言,基础东西还有很多都不会,有些东西也许之前学过,但是我都忘记了。今天忽然看到桌子上的《C Primer Plus》,就拿起来翻了一会儿。翻了十多页,发现整天说的编译-链接-运行,我并不太清楚它这个过程做了什么,只知道编译成机器语言生成目标文件,再链接成可执行文件,反正每次写完源代码后就是一通点击。就去查一下吧。

1.编译型和解释型

  C语言和C++都是编译型语言,相对于解释型语言来说的。编译型的程序在执行之前需要一个专门的编译过程,把源代码编译成机器语言,之后再运行的时候就不用重新编译了。解释型的程序不需要在运行前进行编译,在运行时才会进行翻译成机器语言,看似少了一个编译的过程,但是以后每次执行一次就要翻译一次。

2.编译过程

  最近刚装了Linux的虚拟机(Manjaro),以Linux常用的gcc编译器来说,gcc的编译过程其实是分为四个过程:预处理、编译、汇编、链接。过程如下:
编译过程
1.预处理
  这一步主要就是处理一些#开头的,对文件中的include的文件插入原文件,对于宏定义define这些进行分析,生成.i为后缀的文件。所以我们经常在编译时出错,就要考虑头文件是否有问题。
命令:gcc -E Hello.c -o Hello.i
2.编译
  此时,编译将C/C++代码(也就是预处理后的.i文件)转换成汇编代码,生成以.s为后缀的文件。
命令:gcc -S Hello.i -o Hello.s
3.汇编
  汇编就是将上一步生成的汇编代码转换成机器代码。不只我们看C语言跟看”天书”一样,直接让计算机看C语言代码,它也不懂🤣。将生成以.o为后缀的目标文件(Windows下是.obj文件)。
命令:gcc -c Hello.s -o Hello.o
4.链接
  链接就是将各个模块的相互引用正确地连接起来,最终生成可执行文件。链接又分为动态链接和静态链接,库也分为静库(Linux下的.a,Windows.lib)和动态库(Linux下的.so,Windows下的.dll)

  • 静态链接
      在连接阶段,将源文件中用到的库函数和汇编阶段生成的.o目标文件合并生成可执行文件。也就是引用到的函数库成为可执行文件的一部分。多个运行程序用到某个库函数的时候,内存将会有多个库函数的拷贝。这必定会增加可执行文件占用的空间,并且在库文件要升级的话就要重新编译。但是增加了可移植性,可执行文件放在别的环境就不用考虑库函数的问题了。
  • 动态链接
      动态链接不再将库函数直接加入可执行文件。只是在其中加入了所调用函数的描述信息(通常是重定位信息)。在可执行文件执行时,才会去链接所需库函数。这样可执行文件占用空间较小,并且内存中也只有一个所用库的拷贝。但是当改变运行环境,很有可能找不到函数库。
      程序的时间空间复杂度是趋于平衡的,静态链接后可执行文件占用空间更大,运行时间更短。动态链接每次运行都要重新加载函数库,运行时间更长,但是占用空间更小。
3.gcc常用命令

gcc [选项] [文件]
选项:

  • -E: 预处理,不进行编译、汇编、链接
  • -S: 编译生成汇编语言
  • -c: 汇编生成可执行文件
  • -o: 指定输出文件名
  • -static: 对生成文件采用静态链接
  • -share: 使用动态链接
4.结果

1.Linux下的结果
Linux下gcc例子

2.Windows10下的结果

Win10下gcc例子

5.结语

  虽然看似清楚了,其实平时写小的程序都不会这么一步步来,通常都是这样:
  gcc file.c -o file就直接就产生了可执行文件。
  gcc file.c也可以,没有给定文件输出名,Linux下默认产生的就a.out文件,而在Windows也同样只是产生a.exe文件,就是默认的文件名。
  如果分开进行比较容易知道具体哪一步出错,可以相应的找出错误,一步到位如果出错比较难找。

注: 以上都是个人看法,也许有错的地方,烦请指出,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值