gcc的简介
我们上篇文章中讲解了vim的使用,vim是一款多模式的文本编辑器,我们可以用vim来写代码,代码写完了就该编译了,我们用什么编译?(前提是我们写了一份C语言代码),用的是gcc
如何编译呢?比如我们将代码写在一个名为code.c的文件中,想编译,直接输入指令gcc code.c,会形成一个名为a.out的可执行程序,然后输入 “./a.out”,就可以运行该程序.
(我们之前的文章中提到,在Linux系统中有一个概念,叫"一切皆文件",就是基本所有东西,什么软件,硬件,在Linux系统中都被当做文件看待,不在乎什么后缀,这里我们把前面的code.c改一下名,使用mv code.c code.txt指令,然后gcc code.txt,发现编译报错了,这与我们说的不是矛盾了吗?不矛盾!Linux系统不在意,不代表gcc不在意!(gcc是Linux上的一款软件))
程序的翻译过程
程序的翻译过程需要经过以下几个阶段:
C源文件->预处理->编译->汇编->链接->可执行程序
- 预处理阶段:头文件展开,去注释,条件编译,宏替换
- 编译:c文件转化为汇编
- 汇编:汇编转化为可重定位的二级制文件
- 链接:形成可执行程序
下面我们使用gcc在Linux上验证一下整个过程.
我们先在code.c上写入:
然后输入
gcc -E code.c -o code.i
此时本地形成一份临时文件code.i.那么这个-E是啥意思?从现在开始,帮我进行程序的翻译,等预处理做完就停下来,别往后走了
形成的code.i文件就是经过预处理后的文件,此时,头文件展开了,注释去了,宏也给替换了,没问题.
下面是编译阶段,输入指令:
gcc -S code.i -o code.s
完成编译,形成code.s汇编文件,-S的意思:从现在开始进行程序的翻译,等编译工作做完就停下来
下面是汇编阶段,输入指令:
gcc -c code.s -o code.o
完成汇编,形成code.o二进制文件,汇编做完就停下来
最后进行链接,直接输入
gcc code.o -o mybin
形成mybin可执行程序.
动静态库
经过我们前面的链接形成的可执行文件就能独立运行了吗?
我们现在的所有代码,就是站在巨人的肩膀上写的,有人给我们写好了可以直接使用的函数了,这些函数以库的形式程序,它们在某个位置中
代码+头文件(提供声明)+库(提供实现)=可执行程序
在我们安装开发环境时,会安装下载拷贝头文件和库文件到开发环境的指定路径下,一定要被编译器自己找到
说了这么多,库到底是啥?
首先我们需要了解库的命名:libc.so.6这是一个库名,其中lib是库的前缀,so表示这是一个动态库,6是版本号,所以这个库的名字是c,就是大名鼎鼎的C标准库
(在Linux系统中,动态库用.so表示,静态库用.a表示,Windows系统中,动态库的后缀是.dll,静态库的后缀是.lib)
接下来了解一下动态库和静态库的概念和区别
-
动态库:是C/C++或其他第三方提供的所有方法的集合,被所有程序以链接的方式关联起来(动态链接,库中所有函数都有入口地址,所谓的动态链接,其实就是把要连接的库中的函数地址拷贝到我们的可执行程序的特定位置)
-
静态库:是C/C++或其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的可执行程序中.(静态链接)
-
动态链接的优点:形成的可执行程序体积比较小,比较节省资源.缺点:稍慢,强依赖动态库,动态库没了,依赖这个库的程序都无法运行了
-
静态链接的优点:无视库,可以独立运行 缺点:体积太大,浪费资源
gcc默认链接方式是动态链接,如果想静态链接:
gcc code.c -o code-s -static
发现形成的code-s内存是动态链接形成的文件的几十倍,故系统默认使用动态库.
总结一下,我们的开发环境默认都要为我们做什么?
- 下载开发环境include,lib.
- 设置合理的查找路径.
- 规定好我们形成的可执行程序的链接方式.
最后补充一下,我们编译C文件用gcc,想编译C++,我们可以使用g++,使用方法与gcc基本相同.
本篇文章到此结束,我们主要讨论了gcc的使用和借助gcc实现程序完整的翻译过程,最后又介绍了动静态库的概念.如果文章对您有帮助,请点个赞,如果有错误,请在评论区指正.