目录
前言:
我们目前在使用vim编写的都是C语言的代码,那是因为我们只知道用gcc来编译代码,其实我们还可以用g++来对c++的代码进行编译,那么对gcc的每一步,是怎么将C语言编译形成我们的可执行文件我们是否清楚呢?其实我们在学习c语言预处理的部分我们也讲解过,但是目前我们有必要再从头讲解一次!
常见问题:
我们在第一次使用vim的时候,相信难免会上手体验下vim来编写一些简单的代码,例如一个简单的for循环。
对于上述代码我们使用传统的gcc则会发生编译错误!
这主要是由于咱们的gcc版本太低导致的,我们可以gcc -v查看自己的gcc版本:
对此我们可以输入以下指令来编写该代码:
gcc test.c -std=c99
当然我们也是可以编写C++的代码的,就是将gcc换成g++即可。同理,未来我们在编写C++代码时如果遇到一些错误,可能并不是语法的问题,而是g++的版本过低导致的,那么我们也可以同gcc一样,输入指令:g++ test.cc -std=c++11 即可,这是使用c++11的标准。
程序的翻译过程:
我们在进行讲解的时候需要了解个指令。
使用gcc -o test.exe test.c 目前我们可以理解为将生成的可执行程序的名字改成自己想要的名字。一般我们使用gcc不管编译哪个.c源文件最终都会生成a.out的可执行文件。其实还可以写成:gcc test.c -o test.exe
因此我们可以凭借这行指令对程序的翻译过程进行一个简化。我们在之前的学习c语言的预处理阶段,讲解了程序的翻译过程,如果你忘记了可以去看看之前我写的blog,当然如果你记得一点那就继续往下看吧。
我们需要知道个前提,程序的翻译过程包含4个过程 ——> 预处理、编译、汇编、链接。各个阶段完成都会产生对应的文件,可以通过文件后缀来区分刚进行完什么过程。
总结一下,就会有一个快速记忆的方法,
gcc命令:-ESc
文件后缀:.iso
ESc就如同我们键盘左上角的ESC按键,只不过c是小写而已,而iso则是我们刚开始学linux中讲解到的镜像文件iso,这样就会方便我们记忆。下面我们来说说链接。
链接:
什么是链接?
简单来说就是我们的程序和库的结合的过程,再简而言之,就是我们生成的目标文件代码.o文件,甚至说别的.c文件变成.o文件的代码,然后和库文件通过链接器进行链接从而形成的可执行程序。而每个语言都有自己的标准库,我们在刚开始下载vs2022时,我们在配置开发环境的时候,就是在安装c标准库 + c头文件。
为什么要有链接?
链接过程是由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。
动态链接/静态链接
链接时存在两种连接方式:动态链接、静态链接。而不管是Linux还是Windows都存在动态库以及静态库。
Linux的动态库以.so为结尾而静态库以.a为结尾。
Windows的动态库以.dll为结尾而静态库以.lib为结尾。
动静态链接是怎么做到的呢?
目前我们只需要知道个大概,因为我们后续还会对这部分进行深入了解。我们可以把“网吧”想象为了动态库,而我们去网吧里面玩的电脑可以理解为库函数,例如printf/scanf函数。但是网吧里的每台电脑都不只我们可以用,别人也可以用。而我们去网吧玩电脑其实就是调用库函数,我们可以理解为动态链接。
为什么你要去网吧玩电脑?还不是因为自己家里没有一台合适的电脑,如果家里有了电脑那不是就不需要去网吧玩游戏啦?自己家就是一个静态库,而每次我要玩电脑就只能回家玩,并且电脑也只有自己能用。这就叫做静态链接。
动态链接:去库中执行完返回
静态链接:在编译时,把库中的方法(函数)拷贝到我自己的可执行程序中(不在乎别的库的状态)。
C动态库默认是提供的,gcc默认形成的可执行程序普遍默认动态链接。
优缺点
动态库&&动态链接的优缺点:
- 不能丢失
- 节省资源
静态库&&静态链接的优缺点:
- 一旦形成与库无关
- 浪费资源
验证
默认情况下,Linux上一般静态库都是默认没安装的。输入指令:gcc -o mystatic-test.exe test.c -static 会发现没这个选项
输入指令安装静态库:
sudo yum install -y glibc-static libstdc++-static
接下来再输入:
gcc -o mystatic-test.exe test.c -static
这样就创建好了可执行文件。
下面我们先创建用动态链接的dynamic-test.exe和静态链接的mystatic-test.exe进行验证: