Linux系列-gcc/g++的使用

????个人主页: 羽晨同学

????个人格言:“成为自己未来的主人~”  

程序从书写完成到执行代码一般分为四步,分别是预处理,编译,汇编,连接,这篇文章,我们依据上一篇文章中的代码,来解释一下这四步的操作。

预处理(进行宏替换)

预处理功能主要包括宏定义,文件包含,条件编译和注释的去除等。

预处理指令是以#号开头的代码行。

gcc -E test.c -o test.i

通过这行指令,我们可以进行代码的预处理,-E的作用是让gcc在预处理结束后停止编译过程

-o是指目标文件,i文件为已经经过预处理的c原始程序。

 

比如说,现在我们创建了一个test.c的原始C文件,接下来,我们对他进行预处理。

 经过预处理之后,我们就得到了对应的test.i文件

编译(生成汇编)

在这个阶段当中,gcc首先会检查代码的规范性,看看有没有语法错误,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。

用户可以使用 -S 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

gcc -S test.i -o test.s 

 你看,这样子的话,我们就得到了对应的经过编译之后的程序。 

汇编(生成机器可识别代码)

汇编阶段是把编译阶段生成的.s文件转成目标文件

我们可以使用选项-c 就可看到汇编代码已经转换为对应的二进制目标代码

gcc -c test.s -o test.o

你看,这样子就得到的对应的经过汇编之后的程序文件。

连接(生成可执行文件或者库文件)

在成功编译之后,就进入了链接阶段

gcc test.o -o test

这样子,就得到了对应的文件。

我们可以用过运行test来运行这个代码

这样子,我们就得到了对应的运行结果。

在我们的C语言程序当中,是没有定义printf的实现的,且在stdio.h当中,也只有printf的声明,那么,这个函数是怎么实现的呢?

答案就是:系统把这些函数实现都放到了libc.so.6的库文件中去了,在没有特别指定的时候,gcc会到系统默认的搜索路径/usr/lib下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数printf了,而这也就是链接的作用。

函数库一般分为静态库和动态库两种。

静态库是指编译链接时,把库文件中的代码全部加入到可执行文件中,因此,生成的文件比较大,但在运行的时候也就不需要库文件了,其后缀名字一般为.a

动态库与之相反,在编译链接的时候并没有把库文件的代码加入到可执行文件中,而是在程序执行的时候由运行链接文件加载库,这样就可以节省系统的开销,动态库一般后缀名字是.so,就像前面提到的lib.so.6就是一个动态库,gcc在编译的时候是默认使用动态库的,完成了链接之后,gcc就可以生成可执行文件。gcc默认生成的二进制程序,是动态链接的。

 好了,本次的文章就到这里了,我们下次再见。 

上一篇:Java 批量导出Word模板生成ZIP文件到浏览器默认下载位置


下一篇:【工具变量】中国制造2025试点城市数据集(2000-2023年)