Linux编辑器--gcc_g++的使用
@[toc]
零.前言
众所周知,vim是只能编写代码不能执行代码的,如果想在Linux下执行C或者C++程序时,我们就需要使用Linux下特定的编译器gcc与g++,对比我们经常使用的VS,gcc与g++可以更好地展示一个程序由源文件到可执行文件的过程。
1.由源文件到可执行文件
当我们对一段C语言代码,或者C++代码进行编译运行时,它经过了如下步骤:
1.预处理:删除注释,进行宏替换。
2.编译:生成汇编语言。
3.汇编:汇编语言转换为计算机课识别的机器语言。
4.链接:生成可执行文件或库文件。
在Linux系统中,gcc可以编译C语言程序,g++可以编译C++程序。
注意:为了区分编译,我们把如上四个过程暂时称为翻译过程。
2.直接生成可执行文件并运行
(1)生成可执行文件
首先建立一个名为test.c的文件,向vim中写入代码:
退出vim,由于写入的是C语言程序,我们使用gcc进行翻译。
gcc test.c
此时我们发现生成了a.out文件,该文件就是可执行文件。
(2)运行可执行文件
运行可执行文件很简单,只需要加上./
./a.out
我们发现程序已经成功执行了。
其中.表示当前路径,/表示目录分隔符。
3.分过程生成可执行文件并运行
(1)预处理
gcc -E test.c //如果我们直接执行该命令,预处理的结果会打印在屏幕上。
gcc -E test.c -o test.i //我们可以将预处理的结果放到test.i文件中
注意,必须放入test.i中,因为在下一步编译的过程中,指令只能处理.i的文件。
-E指令的含义是:翻译进行到预处理之后停止。
此时我们打开一下test.i文件:
我们会看到头文件已经在其中进行了展开。几行代码已经变成了几十行。
(2)编译
gcc -S test.i
这里就不用指定文件了,它会自动生成一个.s文件。
-S表示的是翻译进行到编译结束就停下来。
编译时将源代码转换成汇编语言,生成.s文件:
我们可以打开.s文件查看一下汇编代码:
(3)汇编
名为汇编,实际上就是将汇编代码转换为计算机可以读懂的机器码:
gcc -c test.s
此时会形成一个二进制文件test.o,但是当打开它时我们看到的是一个乱码状态,我们需要使用二进制的形式来进行打开:
od test.o
此时我们就可以看到对应的机器码了。
注意即使计算机可以看懂这些二进制编码,但是我们依然不能通过./来执行这个二进制文件。该文件被称为:可重定向目标文件。
(4)链接
命令
gcc test.o
此时生成了可执行文件a.out。
链接的命令很简单,但是要理解链接还需要一些知识的储备。
对链接的理解
链接,即将自己写的程序与语言上的第三方库提供的方法关联起来。编写的C语言链接这个库就可以形成可执行程序。
其中C语言提供了两种库,分别叫静态库和动态库,在Linux系统下分别叫做libc.a与libc.so。
而对应两种库,链接也分为静态链接和动态链接。
举一个栗子:我们在使用printf的时候,我们并没有编写这个函数,printf是在C++标准库中完成的编写,而我们可以使用到它,这是因为我们写的程序与C++标准库完成了链接。
下面画一张图来理解一下:
动态链接:
静态链接:
当我们把库中的相关方法放入我们的程序中的时候,就叫做静态链接,此时不再需要使用任何库。
在gcc中默认的链接方式是动态的链接方式。
两种方式建立可执行程序
动态链接
我们先将a.out改名为test方便对比,然后用file命令列出它的链接信息。
gcc test.o -o test
file test
其中圈起来的部分表示的就是动态链接,括号中的内容表示共享库。
静态链接
gcc test.o -o static_test -static
此时也许你会发现这样的报错,这是因为没有安装C的静态库,需要安装一下:
yum install glibc-static
在root环境下执行这条命令,你就会惊讶地发现,你把静态库安装完了。。
安装完静态库再执行之前的命令:
我们就会发现,我们创建了另一个可执行程序static_test,可以看到它的大小是比test大的,这就是因为把静态库中的方法拷贝到了程序中。
我们同样也可以运行静态库形成的可执行文件,执行结果和test是一样的。
总结:静态链接的时候,需要.o静态库。动态链接的时候,需要.so动态库。
两种链接方式的优缺点
两者各有优缺点:动态链接可以减小可执行程序的大小,节省空间;静态链接的程序可移植性好。
4.g++
g++是C++的编译器,和gcc的使用方法是一样的,我们可以通过-v选项来查看g++的版本:
这里不多赘述了,我们可以用g++来复习一下之前的内容。
touch test.cpp//创建C++程序
vim test.cpp//编写C++程序
g++ test.cpp//直接生成可执行程序
g++ -E test.cpp -o test.i//预处理
g++ -S test.i//编译
g++ -c test.s//汇编
g++ test.o -o test//生成可执行程序
./test//执行可执行程序
我们可以看到运行成功了!
5.总结
我们写代码时,虽说程序和人有一个能跑就行,但是如果程序跑不了呢,就需要进行调试,下一篇文章会详细总结调试器gdb的使用,欢迎大家的高质量评论和三连。
- 点赞
- 收藏
- 关注作者
评论(0)