GCC的编译和调试--入门介绍

本文介绍了GCC编译器的工作原理和编译过程,包括词法分析、语法分析、中间代码生成、代码优化和目标代码生成。同时,详细讲解了GCC的编译器功能,如预处理、编译、汇编和链接,并展示了如何使用gcc编译C程序。文章还提到了gcc的参数设置,如-o用于指定输出文件,-v用于查看编译过程,以及如何通过-g参数为调试准备。在调试部分,介绍了使用gdb进行错误定位,包括设置断点、查看变量值和跟踪执行流程。最后,文章讨论了编译错误的类型,如逻辑错误、语法错误、警告提示,以及处理方法。
摘要由CSDN通过智能技术生成

编译与调试
1.1编译的概念和理解
在进行C程序开发时,编译就是将编写的C语言代码变成可执行程序的过程,这一过程
是由编译器来完成的。编译器就是完成程序编译工作的软件,在进行程序编译时完成了一系
列复杂的过程。
1.1.1程序编译的过程
在执行这一操作时,程序完成了复杂的过程。一个程序的编译,需要完成词法分析、语
法分析、中间代码生成、代码优化、目标代码生成。本章将讲解这些步骤的作用与原理。
(1)词法分析。指的是对由字符组成的单词进行处理,从左至右逐个字符地对源程序进
行扫描,产生一个个的单词符号。然后把字符串的源程序改造成为单词符号串的中间程序。
在编译程序时,这一过程是自动完成的。编译程序会对代码的每一个单词进行检查。如果单
词发生错误,编译过程就会停止并显示错误。这时需要对程序中的错误进行修改。
(2)语法分析。语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规
则的语句。例如,需要检查表达式、赋值、循环等结构是否完整和符合使用规则。在语法分
析时,会分析出程序中错误的语句,并显示出结果。如果语法发生错误,编译任务是不能完
成的。
(3)中间代码生成。中间代码是源程序的一种内部表示,或称中间语言。程序进行词法
分析和语法分析以后,将程序转换成中间代码。这一转换的作用是使程序的结构更加简单和
规范。中间代码生成操作是一个中间过程,与用户是无关的。
(4)代码优化。代码优化是指对程序进行多种等价变换,使得从变换后的程序能生成更
有效的目标代码。用户可以在编译程序时设置代码优化的参数,可以针对不同的环境和设置
进行优化。
(5)目标代码生成。目标代码生成指的是产生可以执行的应用程序,这是编译的最后一
个步骤。生成的程序是二进制的机器语言,用户只能运行这个程序,而不能打开这个文件查
看程序的代码。
1.1.2编译器
所谓编译器,是将编写出的程序代码转换成计算机可以运行的程序的软件。在进行C程
序开发时,编写出的代码是源程序的代码,是不能直接运行的。需要用编译器编译成可以运
行的二进制程序。
在不同的操作系统下面有不同的编译器。C程序是可以跨平台运行的。但并不是说
Windows系统下C语言编写的程序可以直接在Linux下面运行。Windows下面C语言编写的
程序,被编译成exe文件。这样的程序只能在Windows系统下运行。如果需要在Linux系统
下运行,需要将这个程序的源代码在Linux系统重新编译。不同的操作系统下面有不同的编
译器。Linux系统下面编译生成的程序是不能在Windows系统上运行的。
1.2 gcc编译器
gcc是Linux下的C程序编译器,具有非常强大的程序编译功能。在Linux系统下,C语
言编写的程序代码一般需要通过gcc来编译成可执行程序。
1.2.1 gcc编译器简介
Linux系统下的gcc编译器(GNU C Compiler)是一个功能强大、性能优越的编译器。gcc
支持多种平台的编译,是Linux系统自由软件的代表作品。gcc本来只是C编译器的,但是后
来发展为可在多种硬体平台上编译出可执行程序的超级编译器。各种硬件平台对gcc的支持
使得其执行效率与一般的编译器相比平均效率要高20%~30%。gcc编译器能将C、C++源程
序、汇程语言和目标程序进行编译链接成可执行文件。通过支持make工具,gcc可以实施项
目管理和批量编译。
经过多年的发展,gcc已经发生了很大的变化。gcc已经不仅仅能支持C语言,还支持Ada
语言、C++语言、Java语言、Objective C语言、Pascal语言、COBOL语言等更多的语言集的编
译。gcc几乎支持所有的硬件平台,使得gcc对于特定的平台可以编译出更高效的机器码。
gcc在编译一个程序时,一般需要完成预处理(preprocessing)、编译(compilation)、汇
编(assembly)和链接(linking)过程。使用gcc编译C程序时,这些过程是使用默认的设置
自动完成的,但是用户可以对这些过程进行设置,控制这些操作的详细过程。
1.2.2 gcc对源程序扩展名的支持
扩展名指的是文件名中最后一个点的这个点以后的部分。例如下面是一个C程序源文件
的扩展名。
5.1.c
那么这个文件的文件名是“5.1.c”,扩展名是“.c”。通常来说,源文件的扩展名标识源文
件所使用的编程语言。例如C程序源文件的扩展名一般是“.c”。对编译器来说,扩展名控制
着缺省语言的设定。在默认情况下,gcc通过文件扩展名来区分源文件的语言类型。然后根据
这种语言类型进行不同的编译。gcc对源文件的扩展名约定如下所示。
.c为扩展名的文件,为C语言源代码文件。
.a为扩展名的文件,是由目标文件构成的库文件。
.C,.cc或.cpp为扩展名的文件,标识为C++源代码文件。
.h为扩展名的文件,说明文件是程序所包含的头文件。
.i为扩展名的文件,标识文件是已经预处理过的C源代码文件,一般为中间代码文件。
.ii为扩展名的文件,是已经预处理过的C++源代码文件,同上也是中间代码文件。
.o为扩展名的文件,是编译后的目标文件,源文件生成的中间目标文件。
.s为扩展名的文件,是汇编语言源代码文件。
.S为扩展名的文件,是经过预编译的汇编语言源代码文件。
.o为扩展名的文件,是编译以后的程序目标文件(Object file),目标文件经过连接成
可执行文件
此外,对于gcc编译器提供两种显示的编译命令,分别对应于编译C和C++源程序的
编译命令。
1.3 C程序的编译
本章以一个实例讲述如何用gcc编译C程序。在编译程序之前,需要用VIM编写一个简
单的C程序。在编译程序时,可以对gcc命令进行不同的设置。
1.3.1编写第一个C程序
本节将编写第一个C程序。程序实现一句文本的输出和判断两个整数的大小关系。本书
中编写程序使用的编辑器是VIM。程序编写步骤如下所示。
打开系统的终端。单击“主菜单”|“系统工具”|“终端”命令,打开一个系统
终端。
在终端中输入下面的命令,在用户根目录“root”中建立一个目录。
mkdir c
在终端界面中输入“vim”命令,然后按“Enter”键,系统会启动VIM。
在VIM中按“i”键,进入到插入模式。然后在VIM中输入下面的程序代码。
#include<stdio.h>
int max(int i,int j)
{
if(i>j)
{
return(i);
}
else
{
return(j);
}
}
void main()
{
int i,j,k;
i=3;
j=5;
printf("hello,Linux./n”);
k=max(i,j);
printf("%d/n",k);
}
代码输入完成以后,按“Esc”键,返回到普通模式。然后输入下面的命令,保存文件。
:w/root/c/a.c
这时,VIM会把输入的程序保存到c目录下的文件a.c中。
再输入“:q”命令,退出VIM。这时,已经完成了这个C程序的编写。
1.3.2用gcc编译程序
上面编写的C程序,只是一个源代码文件,还不能作为程序来执行。需要用gcc将这个
源代码文件编译成可执行文件。编译文件的步骤如下所示。
打开系统的终端。单击“主菜单”|“系统工具”|“终端”命令,打开一个系统
终端。这时进入的目录是用户根目录“/root”。然后输入下面的命令,进入到c目录。
cd c
上一节编写的程序就存放在这个目录中。输入“ls”命令可以查看这个目录下的文件。
显示的结果如下所示。
输入下面的命令,将这个代码文件编译成可执行程序。
gcc a.c
查看已经编译的文件。在终端中输入“ls”命令,显示的结果如下所示。
a.c a.out
输入下面的命令对这个程序添加可执行权限。
chmod+x a.out
输入下面的命令,运行这个程序。
./a.out
程序的运行结果如下所示。
hello,Linux.
5
从上面的操作可知,用gcc可以将一个C程序源文件编译成一个可执行程序。编译以
后的程序需要添加可执行的权限才可以运行。在实际操作中,还需要对程序的编译进行各
种设置。
1.3.3查看gcc的参数
gcc在编译程序时可以有很多可选参数。在终端中输入下面的命令,可以查看gcc的这些
可选参数。
gcc--help
在终端中显示的gcc的可选参数如下所示。进行程序编译时,可以设置下面的这些参数。
用法:gcc[选项]文件...
选项:
-pass-exit-codes:在某一阶段退出时返回最高的错误码
--help:显示此帮助说明
--target-help:显示目标机器特定的命令行选项
-dumpspecs:显示所有内建spec字符串
-dumpversion:显示编译器的版本号
-dumpmachine:显示编译器的目标处理器
-print-search-dirs:显示编译器的搜索路径
-print-libgcc-file-name:显示编译器伴随库的名称
-print-file-name=<库>:显示<库>的完整路径
-print-prog-name=<程序>:显示编译器组件<程序>的完整路径
-print-multi-directory:显示不同版本libgcc的根目录
-print-multi-lib:显示命令行选项和多个版本库搜索路径间的映射
-print-multi-os-directory:显示操作系统库的相对路径
-Wa,<选项>:将逗号分隔的<选项>传递给汇编器
-Wp,<选项>:将逗号分隔的<选项>传递给预处理器
-Wl,<选项>:将逗号分隔的<选项>传递给链接器
-Xassembler<参数>:将<参数>传递给汇编器
-Xpreprocessor<参数>:将<参数>传递给预处理器
-Xlinker<参数>:将<参数>传递给链接器
-combine:将多个源文件一次性传递给汇编器
-save-temps:不删除中间文件
-pipe:使用管道代替临时文件
-time:为每个子进程计时
-specs=<文件>:用<文件>的内容覆盖内建的specs文件
-std=<标准>:指定输入源文件遵循的标准
--sysroot=<目录>:将<目录>作为头文件和库文件的根目录
-B<目录>:将<目录>添加到编译器的搜索路径中
-b<机器>:为gcc指定目标机器(如果有安装)
-V<版本>:运行指定版本的gcc(如果有安装)
-v:显示编译器调用的程序
-###:与-v类似,但选项被引号括住,并且不执行命令
-E:仅作预处理,不进行编

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值