做三年网站需要多少钱,开发平台都有哪些,网站建设万禾,苏州品牌网站设计#x1f466;个人主页#xff1a;Weraphael ✍#x1f3fb;作者简介#xff1a;目前正在学习c和Linux还有算法 ✈️专栏#xff1a;Linux #x1f40b; 希望大家多多支持#xff0c;咱一起进步#xff01;#x1f601; 如果文章有啥瑕疵#xff0c;希望大佬指点一二 … 个人主页Weraphael ✍作者简介目前正在学习c和Linux还有算法 ✈️专栏Linux 希望大家多多支持咱一起进步 如果文章有啥瑕疵希望大佬指点一二 如果文章对你有帮助的话 欢迎 评论 点赞 收藏 加关注 目录 前言一、 Linux下编译C/C代码二、gcc/g是如何完成代码编译2.1 预处理2.2 编译2.3 汇编2.4 链接 三、库3.1 函数库的概念3.2 动态库3.3 静态库3.4 小结 前言
大家的云服务器可能没有gcc或者g指令如果没有可以分别执行以下指令 sudo yum install -y gcc - gcc指令安装 sudo yum install -y gcc-c g指令安装
注意如果sudo指令有问题的建议先看看这篇博客 - 点击跳转
一、 Linux下编译C/C代码
gcc [.c文件]执行完gcc [.c文件] 后默认会生成可执行文件 a.out 前提是代码没有语法错误 当然也有人想要为这个可执行文件起个名字那么就要通过 -o选项 来实现
gcc [.c文件] -o [新名字]注意g 也可以通过 -o 选项生成指定文件。其指令基本都是一样的 二、gcc/g是如何完成代码编译
由于gcc和g只有编译文件类型不同其他大差不差因此以下就以gcc为例
2.1 预处理
预处理会进行以下操作
去注释头文件展开条件编译宏替换
我们可以直接通过gcc中的-E选项来查看预处理的现象。注意预处理后的文件后缀为.i此时仍然是C语言代码。目的是生成一个干净的C代码程序
gcc -E [.c文件] -o [.i文件] 接下来我们可以打开预处理阶段的文件test.i来看看里面的代码 大家有没有想过这样一个问题头文件展开就是将头文件的内容给拷贝过来那我们怎么知道头文件在哪
其实标准C库头文件如stdio.h、stdlib.h等通常位于 /usr/include 目录下。 当然了标准C库头文件如iostream、vector等通常位于/usr/include/c目录下该目录下还会有不同版本的子目录对应不同的C标准和编译器版本。 2.2 编译
编译阶段会进行语法分析、词法分析、语义分析、符号汇总等然后将合法的代码转为汇编代码。
编译阶段比较重要的一步就是符号汇总它会各种符号汇总起来形成符号表符号表用于各种函数间的相互调用
我们可以直接通过gcc中的-S选项来查看编译阶段的现象。注意编译阶段的文件后缀为.s此时 .s文件里是源文件的汇编代码。
gcc -S [.c文件] -o [重命名为.s文件]
// 注意[.c文件]也可以替换成[.i]文件接下来我们可以打开test.s查看汇编 2.3 汇编
主要任务是将汇编代码转为二进制转为计算机懂的语言并生成符号表
【补充】 什么是符号表
这个东西相当于函数独一无二的地址 C语言的符号是 _函数名 C更详细一些通常为 _Z函数名长度函数名 形参类型的首字母
我们可以直接通过gcc中的-o选项来查看汇编阶段的现象。注意汇编文件后缀为.o此时 .o文件将源文件转化为二进制文件。
gcc -c [.c文件] -o [重命名为.o文件]// 或者可以从[.s文件]开始编译
gcc -c [.s文件] -o [重命名为.o文件]我们可以打开test.o来【欣赏】二进制文件 我们发现是一堆乱码这是一个正常的现象因为test.o本身是二进制文件其而vim是文本编辑器自然而然就看不懂
但是我们可以使用工具 readelf是一个用于查看和分析二进制可执行文件格式elf的工具。
readelf -a [二进制文件]【以下只截取了一部分】 注意二进制文件不可执行需要通过链接才能执行。 2.4 链接
将可重定位目标的二进制文件或称目标文件.o和库进行链接形成可执行文件。
// 两种写法
gcc [.c文件] -o [重命名可执行文件]
gcc [.o文件] -o [重命名可执行文件] 上面说了目标文件需要和库进行链接因此接下来我们来谈谈库。
三、库
3.1 函数库的概念
C程序中并没有定义printf函数我们只是调用函数且在预编译中包含的stdio.h中也只有该函数的声明而没有定义函数的实现。那么是在哪里实现printf函数的呢?
在Linux系统中它把C语言函数实现都被放到名为libc.so的库文件中去了路径/usr/lib64/libc.so。 没有特别指定时gcc会到系统默认的搜索路径/usr/lib下进行查找也就是链接到libc.so库函数中去。
如上图所示在Linux中C语言函数库是一个文件以.so为后缀的称为动态库以.a为后缀的称为静态库。
另外库是有自己的命名规则的。以lib为前缀name为中缀.so.版本为后缀。而库真正的名字只有中缀那一块这也就为什么libc.so称为C语言函数库的原因了。
注意我们现在的机器上默认只会安装动态库静态库是默认没有安装的 【总结】 函数的实现就是在库当中的 库其实就是把源文件.c文件经过一定的翻译然后打包只给你提供一个文件库文件即可不用给你提供给太多的源文件也可以达到隐藏源文件的目的 头文件提供方法的声明 库文件提供方法的实现 我们自己的代码 可执行程序 因此。库的作用不用做很多重复的工作。
3.2 动态库
动态库即通过动态链接的库动态库又称共享库因为动态库中的内容是被所有程序共享的简言之动态库中的代码只需要存在一份程序需要使用时直接通过对应位置调用就行了
在Linux中默认使用 动态链接 的方式我们可以通过 指令ldd来查看文件的链接情况 我们还可以通过 file命令查看文件详细信息 3.3 静态库
静态库采用静态链接的方式静态链接不同与动态链接共享的方式如果程序调用静态库 会将自己所需要的代码拷贝至程序中 完成拷贝后后续不需要再调用静态库。
如果想采用静态链接链接的方式编译程序需要在编译时加上-static选项
gcc [源文件] -o [自己取] -static 而我们开头说了我们的云服务器默认是没有静态库的没有的可以通过sudo yum install -y glibc-static下载。还有我们也可以装一下c的静态库sudo yum install -y libstdc-static 当然我们也可以通过ldd和file指令查看链接情况 由于静态链接是直接将需要的代码拷贝到程序中因此最终生成的文件会变大比较占空间 3.4 小结
【动态库】 优点 动态库因为是共享库有效的节省资源节省磁盘空间内存空间网络空间等 缺点 动态库一旦缺失导致各个程序都无法运行
静态库
优点 程序运行无需依赖库可以独立运行 缺点 体积大比较消耗资源浪费空间