Linux编译器---gcc/g++的使用

文章目录

  • 零.前言
  • 1.由源文件到可执行文件
  • 2.直接生成可执行文件并运行
    • (1)生成可执行文件
    • (2)运行可执行文件
  • 3.分过程生成可执行文件并运行
    • (1)预处理
    • (2)编译
    • (3)汇编
    • (4)链接
      • 命令
      • 对链接的理解
      • 两种方式建立可执行程序
        • 动态链接
        • 静态链接
        • 两种链接方式的优缺点
  • 4.g++
  • 5.总结

零.前言

众所周知,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中写入代码:
Linux编译器---gcc/g++的使用_第1张图片
退出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文件:
Linux编译器---gcc/g++的使用_第2张图片
我们会看到头文件已经在其中进行了展开。几行代码已经变成了几十行。

(2)编译

gcc -S test.i

这里就不用指定文件了,它会自动生成一个.s文件。
-S表示的是翻译进行到编译结束就停下来。
编译时将源代码转换成汇编语言,生成.s文件:
Linux编译器---gcc/g++的使用_第3张图片
我们可以打开.s文件查看一下汇编代码:
Linux编译器---gcc/g++的使用_第4张图片

(3)汇编

名为汇编,实际上就是将汇编代码转换为计算机可以读懂的机器码:

gcc -c test.s

此时会形成一个二进制文件test.o,但是当打开它时我们看到的是一个乱码状态,我们需要使用二进制的形式来进行打开:

od test.o

Linux编译器---gcc/g++的使用_第5张图片
此时我们就可以看到对应的机器码了。
注意即使计算机可以看懂这些二进制编码,但是我们依然不能通过./来执行这个二进制文件。该文件被称为:可重定向目标文件

(4)链接

命令

gcc test.o

此时生成了可执行文件a.out。
链接的命令很简单,但是要理解链接还需要一些知识的储备。

对链接的理解

链接,即将自己写的程序与语言上的第三方库提供的方法关联起来。编写的C语言链接这个库就可以形成可执行程序。
其中C语言提供了两种库,分别叫静态库和动态库,在Linux系统下分别叫做libc.a与libc.so。
而对应两种库,链接也分为静态链接和动态链接。
举一个栗子:我们在使用printf的时候,我们并没有编写这个函数,printf是在C++标准库中完成的编写,而我们可以使用到它,这是因为我们写的程序与C++标准库完成了链接。
下面画一张图来理解一下:
动态链接:
Linux编译器---gcc/g++的使用_第6张图片
静态链接:
Linux编译器---gcc/g++的使用_第7张图片
当我们把库中的相关方法放入我们的程序中的时候,就叫做静态链接,此时不再需要使用任何库。
在gcc中默认的链接方式是动态的链接方式。

两种方式建立可执行程序

动态链接

我们先将a.out改名为test方便对比,然后用file命令列出它的链接信息。

gcc test.o -o test
file test

在这里插入图片描述
其中圈起来的部分表示的就是动态链接,括号中的内容表示共享库。

静态链接

gcc test.o -o static_test -static

Linux编译器---gcc/g++的使用_第8张图片
此时也许你会发现这样的报错,这是因为没有安装C的静态库,需要安装一下:

yum install glibc-static

在root环境下执行这条命令,你就会惊讶地发现,你把静态库安装完了。。
安装完静态库再执行之前的命令:
Linux编译器---gcc/g++的使用_第9张图片
我们就会发现,我们创建了另一个可执行程序static_test,可以看到它的大小是比test大的,这就是因为把静态库中的方法拷贝到了程序中。
我们同样也可以运行静态库形成的可执行文件,执行结果和test是一样的。
在这里插入图片描述
总结:静态链接的时候,需要.o静态库。动态链接的时候,需要.so动态库。

两种链接方式的优缺点

两者各有优缺点:动态链接可以减小可执行程序的大小,节省空间;静态链接的程序可移植性好。

4.g++

g++是C++的编译器,和gcc的使用方法是一样的,我们可以通过-v选项来查看g++的版本:
Linux编译器---gcc/g++的使用_第10张图片
这里不多赘述了,我们可以用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//执行可执行程序

Linux编译器---gcc/g++的使用_第11张图片
我们可以看到运行成功了!

5.总结

我们写代码时,虽说程序和人有一个能跑就行,但是如果程序跑不了呢,就需要进行调试,下一篇文章会详细总结调试器gdb的使用,欢迎大家的高质量评论和三连。

你可能感兴趣的:(linux,运维,c++)