gcc 与 g++ 分别是 gnu 的 C & C++ 编译器 。gcc可以编译C语言程序, g++既可以编译C语言程序, 又可以编译C++程序, 因为在语法上C++兼容C语言。 gcc/g++ 在执行编译工作的时候,总共需要4步:
注:本文中会使用大量Linux中的指令操作还有vim文本编辑器的使用,如果对这些还不太了解的朋友推荐先点击文章底部的文章推荐了解一下使用Linux方面的知识。
利用Linux中gcc操作验证这一过程:
首先,我们用vim编写一段test.c的代码:
#include<stdio.h>
#define N 10
#define HELLO
int main()
{
#ifdef HELLO //条件编译,如果定义了HELLO宏,那就执行ifdef后面的程序,否则执行else
printf("HELLO条件编译已被执行\n");
#else
printf("HELLO条件编译未被执行\n");
#endif
printf("hello A: %d\n",N);
printf("hello B: %d\n",N);
//printf("hello : %d",N);
//printf("hello : %d",N);
//printf("hello : %d",N);
//printf("hello : %d",N);
//printf("hello : %d",N);
printf("hello C: %d\n",N);
return 0;
}
然后我们使用gcc的只激活预处理选项,将生成的文件定向输入到新文件test.i中:
接着使用vim打开test.i文件查看预处理结果:
利用Linux中gcc操作验证这一过程: 首先我们使用gcc的编译到汇编语言选项,将生成的文件定向输入到新文件test.s中:
使用vim打开生成的新文件test.s, 可以发现之前的文件已经被转换成了汇编语言:
利用Linux中gcc操作验证这一过程: 首先我们使用gcc的汇编到二进制机器码选项,将生成的文件定向输入到新文件test.o中:
然后我们使用vim打开新生成的test.o文件, 发现是乱码:
这是因为vim是文本编辑器, 它只能识别文本内容, 不能识别二进制内容, 那么我们可以选择使用二进制查看工具"od"来查看这个二进制文件:
利用Linux中gcc操作验证这一过程: 我们利用gcc来将test.o二进制文件和库连接,生成可执行程序test:
在前面我们提到了gcc工作的最后一步: 连接。那么我们为什么要将自己编写的代码和库连接呢? 这是因为,库中有我们调用的C语言函数的定义, 它们三个的关系如下图:
他们的关系可以给大家举个例子:
也就是说, 我们的C程序中,并没有定义“printf”函数的实现,且在预编译中包含的“stdio.h”中也只有该函数的声明, 而没有定义函数的实现, 系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了, 在没有特别指定时, gcc 会到系统默认的搜索路径“/usr/lib”下进行查找, 也就是链接到 libc.so.6 库函数中去, 这样就能实现函数“printf”了, 而这也就是链接的作用。
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。在Linux中其后缀名一般为“.a”; 在Windows中其后缀名一般为".lib"。 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。在Linux中动态库一般后缀名为“.so”;在Windows中动态库一般后缀名为".dll"。gcc 在编译时默认使用动态库。
看概念有些抽象,我们依然来举个例子,如下图所示:
根据上面的例子也很容易总结出动态库和静态库的特点:
防止有朋友还没有安装C语言/C++的静态库,在这里贴两条安装语句供大家参考:
小tips:
验证gcc 在编译时默认使用动态库:
我们手动要求程序连接静态库:
gcc默认生成的二进制程序,是动态链接的,也可以通过 file 命令验证:
希望这篇关于 gcc/g++编译器 的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.
学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!