gcc编译器:
GNU编译器套件(GNU CompilerCollection)包括C、C++、Objective-C、Fortran、Java、Ada和Go语言的前端
gcc编译器的编译过程:
-
C语言代码解释成为机器可识别的指令需要经过几个阶段:
预处理:展开所有代码
编译:纠错-》将C语言代码编译为汇编代码
汇编:将汇编代码再解释为机器代码
gcc常用选项:
-
-S:生成汇编
-
-I:指定头文件路径
-
-g:包含调试信息
-
-On:n=0~3,编译器优化,n越大优化等级越高
-
-Wall:提示更多的警告信息
-
-D:编译器时定义宏,注意-D和宏之间没有空格
-
-E:生成预处理文件
-
-c:只编译,不链接
-
-C 告诉预处理器不要丢弃注释。配合`-E’选项使用。
-
-M:生成与.c和头文件的依赖关系以用于Makefile,包括系统库的头文件
-
-MM:生成与.c和头文件的依赖关系以用于Makefile,不包括系统库的头文件
-
-o:生成目标文件。假设源文件为file.c,目标文件默认为file.o,汇编文件默认为file.s。
-
gcc -v可以查看gcc的版本信息,但是要是在gcc -v 后面加上一个源文件例如,gcc -v main.c,这样可以获得gcc所使用的系统头文件。
gcc编译生成:
-
默认生成一个a.out这么一个可执行程序
-
我们想要执行这个可执行程序,那么就需要告诉操作系统这个程序文件在哪个位置./a.out
gcc链接过程:
-
我们代码经过汇编以后仅仅是将代码本身解释成为机器代码,但是我们代码中调用的printf函数却不知道在哪里实现,因此这个汇编后的代码是不完全的,所以也就是不是一个完整的额可执行程序。这时候就需要将printf所在的库链接进来。
-
库文件:别人已经实现好的代码打包之后成为一个库,我们直接将库链接过来就可以使用库中的已经实现的代码,而不需要我们自己重新实现。
-
汇编之后将所有的.o文件和所依赖的库合在一起最终生成一个可执行程序。
-
假如将库中所有的代码都链接过来那么造成一个情况:当多个程序运行起来,那么内存中将有非常多的重复代码,这时候关于链接就产生了两种方式
-
-
动态链接:不把库中的代码拿过来。而是仅仅记录一些代码的位置符号信息,在自己代码中,运行的时候才会去找这段的代码。生成的可执行程序比较小,但对库的依赖程度比较高。动态链接链接的是动态库
-
-
静态链接:直接将库中的所有代码拿过来写入到可执行程序中,这样生成的可执行程序比较大,但是对库的依赖程度低。静态链接链接的是静态库
-
库也分了两种:动态库/静态库
-
gcc的链接方式默认是动态链接
新建一个test.c文件
#include <stdio.h>
2
3 int main()
4 {
5 char *ptr = "笑死宝宝啦";
6 printf("%s\n",ptr);
7 return 0;
8 }
gcc编译并且-o重命名
./执行文件