GCC编译器使用指北

GCC相关

1. GCC是是什么?

早期 GCC 的全拼为 GNU C Compiler,即 GUN 计划诞生的 C 语言编译器,显然最初 GCC 的定位确实只用于编译 C 语言。但经过这些年不断的迭代,GCC 的功能得到了很大的扩展,它不仅可以用来编译 C 语言程序,还可以处理 C++、Go、Objective -C 等多种编译语言编写的程序。与此同时,由于之前的 GNU C Compiler 已经无法完美诠释 GCC 的含义,所以其英文全称被重新定义为 GNU Compiler Collection,即 GNU 编译器套件。

所谓编译器,可以简单地将其理解为“翻译器”。要知道,计算机只认识二进制指令(仅有 0 和 1 组成的指令),我们日常编写的 C 语言代码、C++ 代码、Go 代码等,计算机根本无法识别,只有将程序中的每条语句翻译成对应的二进制指令,计算机才能执行。

我们知道,操作系统大致分为 2 大阵营,分别是 Windows 阵营和类 Unix 阵营(包括 Unix、Linux、Mac OS、安卓等)。通常情况下,Windows 系统下用户更习惯使用现有的 IDE 来编译程序;而类 Unix 系统下,用户更喜欢直接编写相应的 gcc 命令来编译程序。

2. 安装GCC编译器
2.1 Linux安装GCC
#查看gcc版本,是否安装
gcc --version
#or
gcc -v

#Ubuntu安装
sudo apt-get install gcc

#CentOS安装
yum -y install gcc
yum -y install gcc-c++
2.2 Windows安装GCC

基于VS Code的C++环境配置/编译/执行/调试

2.3 手动安装指定版本

http://c.biancheng.net/view/7933.html

3. gcc 和 g++ 是什么,有什么区别?

实际使用中我们更习惯使用 gcc 指令编译 C 语言程序,用 g++ 指令编译 C++ 代码。需要强调的一点是,这并不是 gcc 和 g++ 的区别,gcc 指令也可以用来编译 C++ 程序,同样 g++ 指令也可以用于编译 C 语言程序。

实际上,只要是 GCC 支持编译的程序代码,都可以使用 gcc 命令完成编译。可以这样理解,gcc 是 GCC 编译器的通用编译指令,因为根据程序文件的后缀名,gcc 指令可以自行判断出当前程序所用编程语言的类别,比如:

  • xxx.c:默认以编译 C 语言程序的方式编译此文件;
  • xxx.cpp:默认以编译 C++ 程序的方式编译此文件。
  • xxx.m:默认以编译 Objective-C 程序的方式编译此文件;
  • xxx.go:默认以编译 Go 语言程序的方式编译此文件;

当然,gcc 指令也为用户提供了“手动指定代表编译方式”的接口,即使用 -x 选项。例如,gcc -xc xxx 表示以编译 C 语言代码的方式编译 xxx 文件;而 gcc -xc++ xxx 则表示以编译 C++ 代码的方式编译 xxx 文件。有关 -x 选项的用法,后续会给出具体样例。

但如果使用 g++ 指令,则无论目标文件的后缀名是什么,该指令都一律按照编译 C++ 代码的方式编译该文件。也就是说,对于 .c 文件来说,gcc 指令以 C 语言代码对待,而 g++ 指令会以 C++ 代码对待。但对于 .cpp 文件来说,gcc 和 g++ 都会以 C++ 代码的方式编译。

  • 总而言之:对于 C 语言程序的编译,我们应该使用 gcc 指令,而编译 C++ 程序则推荐使用 g++ 指令。
4. GCC自动识别的文件扩展名
文件名称+扩展名GCC 编译器识别的文件类型
file.c尚未经过预处理操作的 C 源程序文件。
file.i经过预处理操作、但尚未进行编译、汇编和连接的 C 源代码文件。
file.cpp file.cp file.cc file.cxx file.CPP file.c++ file.C尚未经过预处理操作的 C++ 源代码文件。
file.ii已经预处理操作,但尚未进行编译、汇编和连接的 C++ 源代码文件。
file.s经过编译生成的汇编代码文件。
file.hC、C++ 或者 Objective-C++ 语言头文件。
file.hh file.H file.hp file.hxx file.hpp file.HPP file.h++ file.tccC++ 头文件。

注意,表中仅罗列了 GCC 编译器可识别的与 C 和 C++ 语言相关的文件后缀名。除此之外,GCC 编译器还支持 Go、Objective-C,Objective-C ++,Fortran,Ada,D 和 BRIG(HSAIL)等编程语言的编译,关于这些编程语言可被识别的文件扩展名,感兴趣的读者可前往GCC官网查看。

如果当前文件的扩展名和表中不符,还能使用 GCC 编译器吗?答案是肯定的。只需要借助 -x 选项(小写)指明当前文件的类型即可。如下:

#编译 hello.shengkai 的C源程序文件
#选项可以是:-xc、-xcpp
gcc -xc hello.shengkai
5. 不同GCC版本支持的C/C++语言编译标准
GCC 版本C语言常用标准
C89/C90C99C11C17GNU90GNU99GNU11GNU17
10.1 ~ 8.4c89 / c90c99c11c17/c18gnu90/gnu89gnu99gnu11gnu17/gnu18
7.5 ~ 5.5c89/c90c99c11gnu90/gnu89gnu99gnu11
4.9.4 ~ 4.8.5c89/c90c99c11gnu90/gnu89gnu99gnu11
4.7.4c89/c90c99(部分支持)c11(部分支持)gnu90/gnu89gnu99(部分支持)gnu11(部分支持)
4.6.4c89/c90c99(部分支持)c1x(部分支持)gnu90/gnu89gnu99(部分支持)gnu1x(部分支持)
4.5.4c89/c90c99(部分支持)gnu90/gnu89gnu99(部分支持)

注意,表头表示的是各个编译标准的名称,而表格内部的则为 -std 可用的值,例如 -std=c89、-std=c11、-std=gnu90 等(表 2 也是如此)。

GCC 版本C++常用标准
C++98/03C++11C++14C++17GNU++98GNU++11GNU++14GNU++17
10.1 ~ 8.4c++98/c++03c++11c++14c++17gnu++98/gnu++03gnu++11gnu++14gnu++17
7.5 ~ 5.5c++98/c++03c++11c++14c++1z(部分支持)gnu++98/gnu++03gnu++11gnu++14gnu++1z(部分支持)
4.9.4 ~ 4.8.5c++98/c++03c++11c++1y(部分支持)gnu++98/gnu++03gnu++11gnu++1y(部分支持)
4.7.4c++98c++11(部分支持)gnu++98gnu++11(部分支持)
4.6.4c++98c++0x(部分支持)gnu++98gnu++0x(部分支持)
4.5.4c++98c++0x(部分支持)gnu++98gnu++0x(部分支持)

表 1、2 中,有些版本对应的同一编译标准有 2 种表示方式,例如对于 8.4~10.1 版本的 GCC 编译器来说,-std=c89 和 -std=c90 是一样的,使用的都是 C89/C90 标准。另外,GCC 编译器还有其他版本,读者可查阅 GCC文档获得相关信息。

6. GCC编译C/C++程序
6.1 一步到位
#一步到位实例,现有hello.c的C源程序文件
gcc hello.c -o hello

#生成了名为hello的二进制可执行文件
6.2 分步编译

C 或者 C++ 程序从源代码生成可执行程序的过程,需经历 4 个过程,分别是预处理、编译、汇编和链接。

gcc/g++指令选项功 能
-E(大写)预处理指定的源文件,不进行编译。
-S(大写)编译指定的源文件,但是不进行汇编。
-c编译、汇编指定的源文件,但是不进行链接
-o指定生成文件的文件名。
-llibrary(-I library)其中 library 表示要搜索的库文件的名称。该选项用于手动指定链接环节中程序可以调用的库文件。建议 -l 和库文件名之间不使用空格,比如 -lstdc++。
-ansi对于 C 语言程序来说,其等价于 -std=c90;对于 C++ 程序来说,其等价于 -std=c++98。
-std=手动指令编程语言所遵循的标准,例如 c89、c90、c++98、c++11 等。

注意,表 1 中仅列出了初学者常用的一些指令选项,事实上这仅是冰山一角,GCC 编译器提供有大量的指令选项,可满足我们在大部分场景下的编译需求。有关更多的编译指令,感兴趣的读者可自行查看 GCC 手册

#分步编译实例,现有hello.c的源文件

#预处理,生成hello.i预处理文件
gcc -E hello.c -o hello.i

#编译,生成hello.s的汇编文件
gcc -S hello.i -o hello.s

#汇编,生成hello.o的目标文件
gcc -c hello.s -o hello.o

#链接,将目标文件作为输入文件,产生可执行文件
gcc hello.o -o hello

#执行
./hello
6.3 补充:GCC -o选项

gcc -o选项用来指定输出文件,如果不使用 -o 选项,那么将采用默认的输出文件。例如默认情况下,生成的可执行文件的名字默认为 a.out。

如下是 gcc -o 指令的使用语法格式:

[root@shengkai]# gcc [-E|-S|-c] [infile] [-o outfile]

其中,用方括号 [] 括起来的部分可以忽略。

[infile] 表示输入文件(也即要处理的文件),它可以是源文件、汇编文件或者目标文件;[outfile] 表示输出文件(也即处理的结果),可以是预处理文件、目标文件、可执行文件等。

8. 使用gcc一次处理多个文件

以下这些操作都可以共用一条 gcc 指令:

  • 将多个 C(C++)源文件加工为汇编文件或者目标文件;
  • 将多个 C(C++)源文件或者预处理文件加工为汇编文件或者目标文件;
  • 将多个 C(C++)源文件、预处理文件或者汇编文件加工为目标文件;
  • 同一项目中,不同的源文件、预处理文件、汇编文件以及目标文件,可以使用一条 gcc 指令,最终生成一个可执行文件。

注意,多个 C(C++)源文件也可以使用一条 gcc -E 指令完成预处理操作,但由于该指令默认情况下只会将预处理结果输出到屏幕上,因此预处理操作虽然可以完成,但无法生成各自对应的预处理文件。

#现有源文件demo1.c, demo2.c

#预处理,默认将预处理结果输出到屏幕上
gcc -E demo1.c demo2.c 

#编译,生成demo1.s和 demo2.s 的汇编文件
gcc -S demo1.c demo2.c

#汇编,生成demo1.o和 demo2.o 的目标文件
gcc -c demo1.c demo2.c

#链接,生成一个可执行文件
gcc demo1.c demo2.c -o demo
#善用*号
gcc *.c -o demo.exe

#执行
./demo
9. 头文件和源文件
  • 通常我们会在头文件中一些类型的定义、结构体定义、宏定义、函数声明、include包含等内容。而在源文件中编写实际的功能实现。

  • 源文件中包含了hello.h这个头文件,于是在这个hello.c文件中就可以使用这些在头文件中定义的内容,可以使用自定义类型、自定义函数、标准输入输出函数等。在使用gcc编译代码时只需要指定hello.c即可编译器会根据#include "hello.h"找到这个头文件,注意hello.h和hello.c要存放在同一个目录下。

  • 值得详细讲述的还有 include的路径问题,当使用<>来指定包含的头文件时,编译器会从系统头文件库中进行查找,而使用""来包含的头文件,编译器将会从当前程序目录进行查找。 在include时被包含文件可以是绝对路径,也可以是相对路径,总之,只要头文件的存放路径与当前源文件的关系正确即可。

  • 另外include不仅仅能包含.h类型的头文件,理论上它可以包含任意类型的文件,例如包含一个.c文件等,但我们通常都用于包含.h类型的头文件

  • 参考

10. 主要参考

[1] C语言中文网

[2] C语言基础:多文件编译

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值