大家好,我是苏貝,本篇博客带大家了解Linux的编译器-gcc/g++,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
目录
- 1.较低版本的gcc/g++编译
-
- [A. gcc编译](#A. gcc编译)
- [B. g++编译](#B. g++编译)
- [C. gcc/g++能否编译C++程序/C语言程序](#C. gcc/g++能否编译C++程序/C语言程序)
- [D. 自定义编译后可执行程序的文件字](#D. 自定义编译后可执行程序的文件字)
- 2.程序的翻译过程
-
- [A. 预处理](#A. 预处理)
- 拓展:在命令行定义宏
- [B. 编译](#B. 编译)
- [C. 汇编](#C. 汇编)
- [D. 链接](#D. 链接)
1.较低版本的gcc/g++编译
A. gcc编译
上图中,为什么编译报错?
因为gcc的版本较低,不能理解在for循环中定义变量i,如果在for循环外定义变量i就没问题
那有什么方法能让较低版本的gcc成功编译呢?
用gcc test.c -std=c99
B. g++编译
我们知道,C语言的后缀名为.c,那么C++的后缀名是什么呢?
我们常用的是.cpp,其实.cc 和.cxx也是
如果没有安装g++,用sudo yum -y install gcc-c++即可安装g++
对于较低版本的g++,用gcc filename -std=c++11,即使用c++11的标准
C. gcc/g++能否编译C++程序/C语言程序
事实上,gcc不能编译C++的程序,但g++能编译C语言的程序
D. 自定义编译后可执行程序的文件字
Linux中编译程序后默认的可执行程序的文件名为a.out,这也可以被修改。
用gcc filename -o you.exe或者gcc -o my.exe filename (-o my.exe 要与filename相邻)。g++同理
2.程序的翻译过程
A. 预处理
说明:头文件展开,去注释,宏替换,条件编译
使用的gcc命令:gcc -E filename -o filename1:从现在开始进行程序的翻译,预处理完成就停下
先来展示头文件展开、去注释和宏替换
打开文件test.i,再vs test.c就可以实现分屏
本来我们的C语言程序只写了16行,但是预处理后的文件有将近700行,多余的就是头文件展开的内容。宏定义的M已经替换为10,注释也被删除了
接下来展示条件编译,test.c文件的内容如下
因为在文件中没有宏定义V1和V2,所以只编译else的内容
现在在test.c 文件中宏定义V1,重新编译test.c文件(gcc -E test.c -o test.i -std=c99),打开test.i,再用vs test.c实现分屏
拓展:在命令行定义宏
Test.c文件的内容:
Gcc命令:gcc -DV1 test.c / gcc -D V2 test.c /gcc -DV3=1 test.c (-D和V1之间可以有空格,也可以没有)
B. 编译
说明:将C变成汇编语言
Gcc命令:gcc -S test.i -o test.s / gcc -S test.c -o test.s :从现在开始进行程序的编译,编译完成后就停下来。(可以从已经预处理过的文件test.i编译,也可以从未经过任何处理的文件test.c编译)
打开编译后的文件test.s,红线框里的都是汇编语言的助记符
C. 汇编
说明:将汇编语言编译成为二进制目标文件
Gcc命令:gcc -c test.s -o test.o / gcc -s test.i -o test.o / gcc -s test.c -o test.o :从现在开始进行程序的翻译,汇编完成后就停下来(可以从已经编译过的文件test.s汇编,已经预处理过的文件test.i汇编,也可以从未经过任何处理的文件test.c编译)
注意:gcc命令的选项-c是小写,预处理和编译的gcc命令的选项-E -S是大写
打开汇编后的文件test.o,里面的内容已经是二进制形式的了
D. 链接
说明:形成可执行程序
Gcc命令:gcc test.o -o my.exe / ... /... /...
现在我们来了解一下链接
链接是什么?
是我们的程序和库结合的过程(语言一定要有自己的标准库)
链接的2种方式:动态链接和静态链接:
Linux中
动态库的后缀: .so
静态库的后缀: .a
Windows中
动态库的后缀: .dll
静态库的后缀: .lib
动态链接:找到共享动态库。一旦动态库缺失,所有的动态链接这个库的程序都无法执行。
静态链接:在编译的时候,把库中的方法拷贝到自己的可执行程序中
Gcc形成的可执行程序,默认采用动态链接
动态库&&动态链接的优缺点:
- 节省资源(同静态链接相比)
- 不能丢失
静态库&&静态链接的优缺点:
- 浪费资源
- 一旦形成,与库无关
因为gcc是默认采用动态链接,所以我们试一试静态链接
Gcc命令:gcc -o newfilename filename -static
可是会报错,因为Linux默认情况下是不会安装静态库的
现在我们来安装一下:
Gcc命令:sudo yum install -y glibc-static
安装完成后,再次动态链接和静态链接。我们发现,静态链接程序的大小约是动态链接的程序的大小的100倍,所以我们才说动态链接更节省资源
也可以通过gcc命令ldd和file来看动态链接和静态链接
好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️