目录
1、gcc
Linux中C语言的编译器为gcc
gcc -E 源文件 从现在开始翻译,完成预处理之后停下来
gcc -S 执行程序的翻译,完成编译工作停下来
gcc -c 执行程序的翻译,完成汇编工作停下来
-o 生成指定的文件(后面要跟要生成的文件名)
注意:(1)预处理:头文件展开、宏替换、条件编译、删注释。
(2)编译之后形成汇编语言
(3)汇编之后形成二进制文件
汇编之后形成的二进制文件并不能直接运行,该文件称为可重定向目标文件。
预处理之后,形成 .i文件
编译之后,形成 .s文件
汇编之后,形成 .o文件
注意:上面的gcc选项,只是了解编译器的工作过程,实际使用时,并不需要一步步的生成。正常使用gcc时就如下图所示即可。
2、初识链接
语言给我们提供了一套头文件和一套库文件,需要链接来将我们自己代码中的函数调用、外部数据和库中相关联。
例如:上述c程序中,我们使用的printf函数,我们只是调用了该函数,但是printf函数是如何将字符串打印到显示器上的,我们没关心。因此需要在汇编之后,再进行链接工作,将该函数与库里的相关联。
3、如何理解c程序的翻译过程
为什么c程序的翻译过程是预处理、编译、汇编、链接这个过程,说起这个问题,还要追溯到计算机的发展史。
由于计算机只认识二进制,且早期时并没有很好的编程语言。所以人们只能通过一系列的0、1序列来操纵计算机。例如:通过纸带打孔的方式,有孔无孔就是对应的0和1。但是二进制编程效率低,所以又引出了助记符,也就是汇编语言,因为计算机只认识二进制序列,所以便有了编译器。后来人们又推出c语言,以及后面的面向对象的高级语言。因为历史是这样发展的,所以c的翻译工作就是倒着来的。
问:通过上述的小故事,了解了编译与汇编,但是为什么要有预处理阶段呢?
答:因为c语言从语法层面提供了许多特性,例如:注释。所以需要预处理阶段,对源代码进行预处理工作,对于注释,那就是删注释。
问:那为什么还要有链接这个步骤?
上述已经阐述了,链接是将自己的代码与库里的相关联,能调用别人写的东西,也就是不需要自己写了,可以提高开发效率。
4、初始动/静态链接
问:链接是如何将自己的代码与库里的相关联呢?
首先先认识以下知识:
ldd 可执行程序 查看可执行程序所依赖的第三方库
Linux中的库分为:静态库 .a
动态库 .so
如何理解动态链接、静态链接?
下面将通过小故事回答这个问题:
静态链接:将库中有关的代码拷贝到自己的程序中。
由于静态链接会将库中的代码拷贝到程序中,所以生成的可执行程序的内存体积可能比较大,相对的可移植性比较好。
由于动态链接会到对应的库中执行相应的代码,拿到结果后返回,接着刚刚的继续运行,所以生成的可执行程序所占内存体积小,但是比较依赖库。
具体的链接细节,会在后续的博客中写到。现在只需要知道,静态链接的时候,需要.a静态库,动态链接的时候,需要.so动态库。
Linux是默认采用动态链接,如果需要静态链接,需要在命令行后添加 -static选项
gcc test.c -o test -static
5、g++
Linux中C++的编译器为g++
用g++编译器,前提是Linux中安装了g++
g++ -v 查看g++编译器的版本号
g++的操作与上述gcc基本相同,这里不做赘述,下面将通过一个示例来演示相关使用: