菜鸟笔记
提升您的技术认知

gcc和g 的使用-ag真人游戏

linux环境基础开发工具使用—gcc和g 的使用

  • 1.程序的翻译环境
    • ①预处理
    • ②编译
    • ③汇编
  • 2.链接

①预处理

在一个.c文件被编译的时候,他第一个经历的步骤就是预处理,预处理是什么呢?我先抛出概念,后面就做出论证。
预处理它是先把我们的头文件展开,比如我们的stdio.h,然后还有宏定义的替换也是这个阶段做的,我们的条件编译也是同理,都是#开头的预处理指令。预处理还有一个作用那就是去注释,大概就是这些。

首先我们,先创建一个.c文件,在里面编写代码,如果对vim不了解的,可以看我的另一篇博客:vim的使用

在里面,我编写了一个简单的程序,里面包含了头文件,条件编译,#define定义的标识符和注释



首先解释一下gcc -e test.c -o test.i这条指令的意思

gcc是我们c语言的编译器
-e的意思是现在开始进行程序的翻译,预处理做完就停下来
-o的意思你所要形成的目标文件的名字,后面跟的一定是新文件名
.i是经过预处理后的文件后缀

经过这条指令,大家可以发现新生成了一个test.i,进入可以看到里面一共有800多行,和我们一开始编写的代码行数相差甚远,我们看文件的最后,可以发现我们的头文件已经不见了,注释也消失了,#define定义的标识符也已经被替换了,条件编译也已经被处理过了。这就论证了前面所说的,其实上面的一大堆,800多行,就是头文件的展开,条件编译由于定义了max,他为真,因此留下了打印的那行代码。

②编译

翻译环境下的第二步骤就是编译,在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言,即把c语言翻译成汇编语言
先介绍一下他的命令:

-s:从现在开始进行程序的翻译,当编译做完就停下来
.s:经过编译后的文件后缀



确实,我也看不懂,哈哈哈,总之,知道他是汇编语言就好

③汇编

汇编就是把汇编语言转换成可重定位目标二进制文件,不过他不可以执行,他在windows系统下,他就是.obj后缀的文件,讲的简单一点就是他从汇编语言被转换成了机器语言(二进制)。
依旧先讲一下指令

-c:从现在开始进行程序的翻译,当汇编做完,就停下来
.o:经过汇编,生成的文件的后缀,注意他与windows系统下的不同,windows下是.obj


上图,即window下的可重定位目标二进制文件


里面就是机器语言,那就更看不懂了,哈哈哈

链接也是翻译环境下的一部分,但它非常重要,所以说拎出来讲,链接是翻译环境的最后一步,完成之后他就会生成可执行文件,首先我们先来讲一下指令

gcc test.c:到这一步的时候已经不需要再有命令选项了,可以直接链接,最后会生成a.out,这是linux下默认的
gcc test.c -o test:如果想自己命名,那就加上-o



现在问题来了,我们的c程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到
系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。

其实安装vs的时候,实际上最重要的一个工作就是帮我们下载并安装语言的头文件和库文件
linux系统默认已经携带了语言级别的头文件和语言对应的库
库分为两种,静态库和动态库,库本质也是文件
静态库:libxxx.a
动态库:libxxx.so
xxx是库名,a后缀的是静态库,so后缀的是动态库
可以使用ldd命令来查看程序运行所需要的动态库

大家只要关注第二行就可以了,他所用的正是libc.so.6这个动态库

1.库分为静态库(专门让编译器对用户的程序进行静态链接的)和动态库(专门让编译器对用户程序进行动态链接的)
2.静态库和静态链接:链接的时候,如果是静态链接,找到静态库,拷贝静态库中我们所需要的代码到我们自己的可执行程序中
3.动态库和动态链接:链接的时候,如果是动态链接,找到动态库,拷贝动态库中我们所需要代码的地址到我们自己的可执行程序中的相关位置
4.静态库链接成功:我们的程序,不依赖任何库,自己就可以独立运行
5.动态库链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序便无法运行!
6.静态库:因为自身拷贝的问题,比较浪费空间
7.动态库:因为可以做到被大家共享,所以说也叫做共享库,真正的实现永远都在库中,程序内部只有地址,比较节省空间
8.linux下默认使用的是动态链接和动态库,并且一般的云服务器默认都是只有动态库,其实也更建议使用动态库,因为当一个项目很大后,他所浪费的内存也是很大的
下载c的静态库的指令:yum install -y glibc-static
下载c 的静态库的指令:yum install -y libstdc ±static
-static:在使用gcc命令时带上这个命令选项就可以使用静态链接了



大家可以清晰的看到生成的两个可执行文件的大小是差很大的,所以说一般都是使用动态链接。
虽然只讲了gcc,但是g 也是一样的道理,命令什么的都是一样的。

网站地图