程序的翻译
- 1 快速认识gcc/g++
- 2 程序翻译的过程
- 2.1 预处理阶段
- 2.2 编译阶段
- 2.3 汇编阶段
- 2.4 链接阶段
- 3 动静态库
1 快速认识gcc/g++
首先我们需要在linux系统中安装对应的编译器gcc/g++,安装命令如下(centos7环境下):
gcc: yum install gcc
g++: yum install gcc-c++
直接说明结论吧,gcc既可以编译C语言代码,又可以编译cpp代码,但是g++只能编译cpp代码!这个可以分别写一个cpp代码与c代码,用这两个编译器进行编译!我们就以gcc来说明程序翻译的过程(g++的原理也是类似的)!
2 程序翻译的过程
2.1 预处理阶段
预处理阶段所要做的工作就是
头文件展开,去注释,宏替换,条件编译
!
头文件展开就是将头文件中的内容拷贝到源文件中,去注释就是把相应注释去除掉
,有宏定义的变量要把它替换掉,这里主要就是说下条件编译,就是编译满足条件的内容!下面我来举个简单的例子来说明一下什么事条件编译吧!首先我们在Linux中建立一个C语言文件,命名为test1.c。内容如下所示:
5 #include <stdio.h>
6 int main(){
7 #ifdef version1
8 printf("version1");
9 #elif version2
10 printf("version2");
11 #else
12 printf("free version");
13 #endif
14 return 0;
15 }
~
我们使用以下命令就可以实现条件编译了
gcc test1.c -D version2
此时我们利用条件编译就可以打印出version2了,了解这个条件的编译的目的就是为了让我们知道,我们可以通过给编译器传递不同的宏值,从而实现我们代码的动态裁剪。以及有些软件分为社区版与专业版本质就是利用了条件编译!
在大概了解完预处理阶段要做的事情,我们在linux中也可以使用命令来才看经过预处理之后的代码!在Linux中建立了一个test.c文件,使用如下命令:
gcc -E(完成预处理工作就行) test.c -o(取别名) test.i
在预处理阶段之后,实际上是会生成一个以点i结尾的文件,所以这里就对test.c经过预处理之后取了一个别名test.i
2.2 编译阶段
程序编译阶段实际上就是把我们的C语言代码翻译成汇编代码,生成一个以点s结尾的文件
命令:gcc -S(完成编译阶段) test.i -o test.s
2.3 汇编阶段
汇编阶段就是把我们的汇编代码翻译成二进制!生成一个以点o结尾的文件
命令:gcc -c (完成汇编阶段,注意这里c是小写)test.s -o test.o
2.4 链接阶段
链接阶段就是将我们生成以点o结尾的文件与库里面的对应的点o文件相链接,只要我们使用了库中的函数如:printf,scanf等。
3 动静态库
在Windows下,动态库是以dll为结尾的文件,静态库是以lib结尾的文件!而在Linux系统下,动态库是以so结尾的文件,静态库是以a结尾的文件!本节中,我们简单的先了解一下什么是动态库,什么是静态库!
首先我们先来理解一下什么是动态库吧,以下图为例!
首先我们的代码片段会加载到内存中,生成以点o结尾的文件之后,根据代码就会知道动态库的地址,从而在动态库的文件中找对应的点o文件进行链接,这种链接方式就叫做动态链接!所以静态库就是程序会知道静态库的地址,然后将所需的库文件从静态库拷贝一份到源文件中!这种方式就叫做静态链接!我们需要注意的是动态库与静态库还是有区别的,至于具体的区别是什么,在之后的学习过程中,我们还要进一步的进行学习!在了解完什么是静态链接与动态链接之后,在Linux系统下,默认的就是动态链接,如下图所示:
动态链接编译:gcc test.c -o test.exe
ldd命令就可以查看文件所依赖的库文件,file命令就可以查看文件的链接属性了
我们如果想要进行静态链接,就必须先在Linux环境中安装静态库!命令如下所示:
sudo yum install -y glibc-static
如下图所示,就是静态链接的查看
静态链接的编译:gcc test.c -o test-static.exe -static
我们再来看下动静态库的区别
我们可以发现,动态库的优点就是节省资源(网络,内存等),不会有过多的重复代码!缺点就是对库的依赖性很高,要是库文件没用,那么程序无法运行!静态库的优缺点正好与动态库是相反的!
总结一下,程序的翻译过程就可以用下面这张图来形象的进行概括!