wordpress激活,大型网站seo策略,搜索引擎是什么,沈阳京科医院文章目录 1.背景知识2.gcc如何完成编译运行工作预处理#xff08;进行宏替换#xff09;编译#xff08;生成汇编#xff09;汇编#xff08;生成机器可识别代码#xff09;链接#xff08;生成可执行文件#xff09; 3.函数库动态库静态库动静态库的区别 4.gcc选项 1.… 文章目录 1.背景知识2.gcc如何完成编译运行工作预处理进行宏替换编译生成汇编汇编生成机器可识别代码链接生成可执行文件 3.函数库动态库静态库动静态库的区别 4.gcc选项 1.背景知识
通过前面的学习我们知道我们的代码变成能运行的可执行程序要经历以下四个过程 1.预处理进行宏替换 2.编译生成汇编 3.汇编生成机器可识别的代码 4.链接生成可执行文件或库文件 那在Linux操作系统上gcc编译器编译运行代码的过程又是怎么样的呢接下来让我们一起学习吧
2.gcc如何完成编译运行工作
$ 格式 gcc [选项] 要编译的文件 [选项] [目标文件]创建mycode.c文件写入如下代码
#includestdio.h
#define M 100 int main()
{
#ifdef DEBUG printf(hello debug\n);
#else printf(hello release\n);
#endif // pintf(这是被注释掉的内容\n); // pintf(这是被注释掉的内容\n); // pintf(这是被注释掉的内容\n); // pintf(这是被注释掉的内容\n); // pintf(这是被注释掉的内容\n); // pintf(这是被注释掉的内容\n); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); printf(hello gcc:%d\n,M); return 0;
} 指令
$ gcc -o mycode.exe mycode.c
//-o 可以指定生成可执行文件名称如果不指定默认生成a.out可执行文件代码编译运行的结果为
预处理进行宏替换
预处理指令
$ gcc -E 源文件 -o 指定预处理文件名预处理阶段是源文件文件转成目标文件选项-E,该选项的作用是让 gcc 在预处理结束后停止编译过程。选项“-o”是指目标文件如果不带选项“-o”会预处理的结果放在显示屏上“.i”文件为已经过预处理的C原始程序。预处理阶段的主要工作有a.去注释b.头文件展开c.宏替换不做类型检查d.条件编译
输入指令
$ gcc -E mycode.c -o mycode.i
$ gcc -E mycode.c -o mycode.i -D DEBUG//使用-D选项在外部可定义宏输入该指令告诉gcc从现在开始程序的翻译做完预处理工作就停下来不要继续往下执行了。 输入指令vim mycode.i查看预处理后的文件 头文件展开
编译生成汇编
输入编译指令
$ gcc -S mycode.i -o mycode.s编译阶段是把预处理阶段生成的“.i”文件转成.s目标文件在这个阶段中gcc 首先要检查代码的规范性、是否有语法错误等以确定代码的实际要做的工作在检查无误后gcc 把代码翻译成汇编语言。用户可以使用“-S”选项来进行查看该选项只进行编译而不进行汇编生成汇编代码。
代码运行的结果为
汇编生成机器可识别代码
汇编指令
$ gcc -c mycode.s -o mycode.o汇编阶段是把编译阶段生成的“.s”文件转成.o目标文件可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了 输入指令的结果为 mycode.o为可重定位二进制文件简称目标文件Windows上目标文件为.obj文件虽然已经是二进制文件但是还不可以独立执行需要经过链接才能执行 链接生成可执行文件
$ gcc mycode.o -o mycode.exe在成功编译之后就进入了链接阶段将可重定位二进制文件和库进行链接形成.exe可执行文件
3.函数库
函数库概念 我们的C程序中并没有定义“printf”的函数实现且在预编译中包含的“stdio.h”中也只有该函数的声明而没有定义函数的实现那么是在哪里实“printf”函数的呢? 系统把这些函数实现都被做到名为 libc.so.6的库文件中去了在没有特别指定时gcc会到系统默认的搜索路径“/usr/lib”下进行查找也就是链接到libc.so.6库函数中去这样就能实现函数“printf”了而这也就是链接的作用 动态库
windows系统中动态库以.dll为后缀的文件Linux系统动态库为以.so为后缀的文件。库的命名规则“libnameso.XXXname为库的真正名字其他为前后缀。 输入指令查找C的标准库
ls /lib64/libc*
//查找含/lib64/libc的库文件
ls /lib64/libc.so*
//查找动态库文件输入指令后代码运行的结果
静态库
windows系统中静态库以.lib为后缀的文件Linux系统静态库为以.a为后缀的文件。我们的机器上默认只会安装动态库静态库需要我们手动输入指令安装。 安装C语言静态库指令如下
//root用户
# yum install -y glibc-static//安装c的静态库
# yun install -y libstdc-static//安装c的静态库
//普通用户
$ sudo yum install -y glibc -static
$ yun install -y libstdc-static安装完成的结果如下
查找C语言静态库指令
$ ls /lib64/libc.a*输入指令后代码运行的结果
动静态库的区别 小故事 网瘾少年需要上网你有两种方法一种是跑到网吧上网而你怎么知道哪里有网吧呢原来你的好基友曾经告诉你某某路口向东转500米有一家网吧于是每到放假的时候你就可以跑到网吧去上网但天有不测风云这家网吧的老板没有营业执照被查封了自此你的上网之路就断了只好使用另一种方法你每天上省吃俭用终于三个月后攒够了钱去一家二手电脑销售店购买了一台电脑从此你便过上了自由自在的网民生活不久后你去的这家二手电脑销售店由于非法经营被查封了但这已经影响不到你了。 动态链接.o文件网瘾少年和动态库网吧链接很高效但如果动态库没了各个程序文件将无法运行限制性很大静态链接.o文件网瘾少年会拷贝购买静态库电脑到文件中会占用很大内存、很多时间费时费钱但库文件电脑销售店没了不存在了各个程序文件不受影响仍可以正常运行 生成可执行文件的指令
$ gcc mycode.c -o mycode.exe//进行动态链接
$ gcc mycode.c -o mycode_static.exe -static//进行静态链接输入指令后代码运行的结果
ldd 可执行文件//查找链接的动态库file 可执行文件名//显示符号链接的文件类型①在Linux中编译形成可执行程序由编译器提供动态库默认采用动态链接如果想要以静态链接的方式生成可执行文件需要添加-static选项②静态链接生成的可执行文件比动态链接生成的可执行文件大很多。 动静态库区别总结 ①如果没有静态库不可以使用-static选项进行静态链接 ②如果没有动态库只有静态库gcc编译器将会去寻找静态库进行链接 ③gcc默认优先动态链接-static选项改变的是链接的优先级使用后所有的链接都为静态链接 ④我们平时写的代码生成可执行文件时不一定全部是动态链接或静态链接而极有可能是动态链接和静态链接混合生成可执行文件 ⑤动态链接优点动态库是共享库可以有效地节省资源磁盘空间、内存空间网络空间等缺点动态库一旦缺失使用动态链接的可执行程序将无法运行 ⑥静态链接的优点不依赖库程序可以独立运行缺点生成的可执行文件体积大比较消耗资源磁盘空间、内存空间网络空间等。
4.gcc选项 -E 进行预处理工作不生成文件你需要把它重定向输出到一个.i文件里面 -S 编译到汇编语言到.s文件中不进行汇编和链接 -c 进行汇编工作编译到.o可重定位二进制目标文件目标文件 -o 将目标文件和库文件进行链接输出到指定的可执行文件 -static 此选项对生成的文件采用静态链接 -g 生成调试信息。GNU 调试器可利用该信息。 -shared 此选项将尽量使用动态库所以生成文件比较小但是需要系统由动态库 -O0 -O1 -O2 -O3 编译器的优化选项的4个级别-O0表示没有优化-O1为缺省值-O3优化级别最高 -w 不生成任何警告信息。 -Wall 生成所有警告信息。