Linux 下C语言编程
1.编程的概念和理解
1.1程序编译的过程
在这一操作中,程序完成了复杂的过程。一个程序的编译,需要完成词法分析、语法分析、中间代码生成、代码优化、目标代码生成。
l 词法分析:指的是对由字符组成的单词进行处理,从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。然后把字符串的源程序改造成为单词符号串的中间程序。在编译程序时,这一过程是自动完成的。编译程序会对代码的每一个单词进行检查。如果单词发生错误,编译过程就会停止并显示错误。这是需要对程序中的错误进行修改。
l 语法分析:语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语句。例如:需要检查表达式、赋值、循环等结构是否完整和符合使用规则。在进行语法分析时,会分析出程序中错误的语句,并显示出结果。如果语法发生错误,编译任务是不能完成的。
l 中间代码生成:中间代码是源程序的一种内部表示,或称中间语言。程序进行词法分析和语法分析以后,将程序转换成中间代码。这一转换的作用是使应用程序的结构更加简单和规范。中间代码生成操作是一个中间过程,与用户无关。
l 代码优化:指对程序进行多种等价变换,使得从变换后的程序能生成更有效的目标代码。用户可以在编译程序时设置代码优化的参数,可以针对不同的环境和设置进行优化。
l 目标代码生成:指的是产生可以执行的应用程序,这是编译的最后一个步骤。生成的程序是二进制的机器语言,用户只能运行这个程序,而不能打开这个文件查看程序的代码。
1.2编译器
编译器是将编写出的程序代码转换成计算机可以运行的程序的软件。在进行C程序开发时,编写出的代码是源程序是代码,是不能直接运行的。需要用编译器编译为可以运行的二进制程序。
在不同的操作系统下面有不同的编译器。C程序是可以跨平台运行的。但并不是说Windows系统下C语言编写的程序可以直接在Linux下面运行。Windows下面用C语言编写的程序,被编译成exe文件,这样的程序只能在Windows系统下运行。如果在Linux系统下运行,需要将这个程序的源代码在Linux系统下重新编译。不同的操作系统下面有不同的编译器。Linux下面编译生成的程序是不能在Windows系统上运行的。
2.gcc编译器
gcc是Linux下能用的C程序编译器,具有非常强大的程序编译功能。在Linux系统下,C语言编写的程序代码一般要通过gcc编译成可执行程序。
2.1.gcc编译器的简介
2.2.gcc对源程序扩展名的支持
扩展名指的是文件名中最后一个点以后的部分。
.c为扩展名的文件,为C语言源代码文件。
.a为扩展名的文件,是由目标文件构成的库文件。
.C、.cc、.cpp为扩展名的文件,标识为C++源代码文件。
.h为扩展名的文件,说明文件是程序所包含的头文件。
.i为扩展名的文件,标识文件是已经预处理过的C源代码文件,一般为中间代码文件。
.ii为扩展名的文件,标识文件是已经预处理过的C++源代码文件,一般为中间代码文件。
.o为扩展名的文件,是编译后的目标文件,源文件生成的中间目标文件。
.s为扩展名的文件,是汇编语言源代码文件。
.S为扩展名的文件,是经过预编译的汇编语言源代码文件。
3.C语言的编译
3.1. 编写一个C程序
用vim编写一个C程序:vim a.c
3.2. 用gcc编译程序
输入命令gcc a.c ,会生成一个a.out文件
用命令chmod +x a.out 对这个程序添加可执行权限。
输入命令./a.out 运行这个程序
3.3. 查看gcc的参数
查表 --help
-o常用
4. 编译过程的控制
编译过程指的是gcc对一个程序进行编译时完成的内部处理和步骤。编译程序时会自动完成预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)四个步骤。
4.1. 编译过程简介
gcc把一个程序的源文件,编译成一个可执行文件,中间包括很多复杂的过程。可以用图来表示编译中四个步骤的作用和关系。
? 预处理:
? 编译:
? 汇编:
? 链接:
5.gdb调试程序
所谓调试,指的是对编好的程序用各种手段进行查错和排错的过程。进行这种查错处理时,并不仅仅是运行一次程序检查结果,而是对程序的运行过程、程序中的变量进行各种分析和处理。
5.1. gdb 简介
gdb 是一个功能强大的调试工具,可以用来调试C程序或C++程序。在使用这个工具进行程序调试时,主要使用gdb进行下面4个方面的操作。
? 启动程序:在启动程序时,可以设置程序运行环境。
? 设置断点:断点就是可以在程序设计时暂停程序运行的标记。程序会在断点出停止,用户便于查看程序的运行情况。这里的断点可以是行数、程序名称或是条件表达式。
? 查看信息:在断点停止后,可以查看程序的运行信息和显示程序变量的值。
? 分步运行:程序可以一个语句一个语句的执行,这时可以及时地查看程序的信息。
? 改变环境:可以在程序运行时改变程序的运行环境和程序的变量。
5.2. 在程序中加入调试信息
为了使用gdb进行程序调试,需要在编译程序中加入供gdb使用的调试信息。方法是在编译程序时使用一个 -g 参数。在终端中输入下面的命令,在编译程序时加入调试信息。
gcc -g -o a.debug a.c
这时,编译程序a.c,会生成一个a.debug的可执行程序。这个可执行程序中加入了供调试所用的信息。
5.3. 启动gdb
在调试文件以前,需要启动gdb。在终端输入命令gdb打开
这时,gdb的启动信息如下所示。这些提示显示了gdb的版本和版权信息。
5.4. 在gdb中加载需要调试的程序
使用gdb调试一个程序之前,需要加载这个程序。加载程序的命令是file。在(gdb)提示符后面输入下面的命令加载程序a.debug
file a.debug
命令的运行结果如下所示,显示已经加载了这个文件,并且使用了系统库文件。
5.5. 在gdb中查看代码
用gcc命令编译程序加入了 -g 命令以后,编译后的a.debug程序中加入了断点。可以用list 命令显示程序的源代码和断点。下面的步骤是查看加入断点以后的代码。
① 在(gdb)提示符后面输入下面的命令。
list 1
② 这时,gdb会提示第一个断点以前的代码。
③ 这时,按“Enter”键,显示下一个断点以前的代码。
④ 按“Enter”键,显示下一个断点以前的代码。
5.6. 在程序中加入断点
程序会运行到断点的位置停止下来,等待用户处理信息或查看中间变量。如果自动设置的断点不能满足调试要求,可以用break命令增加程序的断点。
例如需要在程序第6行增加一个断点,可以输入 下面的命令
break 6
这时gdb显示的结果如下所示:
在程序的第18行、第19行、第21行增加断点。
break 18
break 19
break 21
5.7. 查看断点
命令“info breakpoint ”可以查看程序中设置的断点。
加上相应的断点编号,可以查看这个断点的信息。
5.8. 运行程序
gdb 中的run 命令可以使这个程序以调试的模式运行。下面的步骤是分步运行程序,对程序进行调试。
① 在(gdb)提示符后输入“run”命令,显示的结果如下
② 结果显示了程序中的异常,并将异常记录到了系统文件中。然后在程序的第二个断点的位置第18行停下。
③ 这时输入“next/step”命令,程序会在下一行停下,结果如下。
④ 输入“continue”命令,程序会在下一个断点的位置停下。
⑤ 输入“continue”命令,程序运行到结束。结果如下。
注意:“step”命令与“next”命令的作用相似,对程序实现单步运行。不同的是,在遇上函数调用时,“step”命令可以进行到函数内部。而“next”命令只是一步完成函数的调用。
5.9. 变量的查看
“print”命令可以在程序的运行中查看一个变量的值。
① 程序在第一个断点的位置停下。程序进入第18行之前停下,并没有对i进行赋值。用下面“print i”命令来查看,结果显示i现在只是一个任意值。