说明:为了匹配嵌入式实验开发板,本系列博文所用的Ubuntu系统均为16.04版本。
一、C程序的编辑
Ubuntu-vim 在所有linux里都有一套文本编辑器,vim,则是高级版的vi。 vim是Linux系统内置的「文本编辑器」,用于查看或编辑文件的内容,学会使用vim编辑器,将在Linux终端中畅通无阻。 vim具有程序编辑的能力,可以主动以字体颜色辨别语法的正确性,方便程序设计。
1、vim文本编辑器
Ubuntu 16.04 默认没有安装vim编辑器,初次使用需要安装。安装命令如下:
sudo apt install vim
安装过程很简单,首先输入上述安装命令,然后根据提示输入“Y”,即可完成安装。 安装完成后,也可以通过查询版本命令查询是否安装成功。
2、vim编辑器的使用
vim编辑器有三种模式:命令模式、插入模式、底行模式。
1)命令模式
「命令模式」:可以进行移动光标、复制/粘贴/删除、搜索替换等快捷操作。
打开文件后,默认就是命令模式。
注意:命令模式中,敲击的键盘会被识别为命令,而不是输入内容。
在命令模式下,移动光标操作指令为:
在命令模式下, 复制/粘贴/删除指令为:
在命令模式下 ,搜索替换指令为:
2)插入模式
命令模式(command mode)下输入“i” 键即可进入「插入模式」(Insert mode) ,下方则会一直出现INSERT (不管输入i还是a都会出现INSERT),如下图,表明是编辑状态。 编写完之后按 “ESC” 键即可退出 “插入模式(Insert mode)”
「插入模式」或「编辑模式」:可以编辑文件内容。
3)底行模式
「底行模式」:或末行模式,可以通过命令操作文件,比如搜索、保存、退出等。
在插入模式下,编写完C程序,按 “ESC” 键即可退出 “插入模式(Insert mode)”,回到命令模式。
在命令行模式下,按一下 “ shift+ : 键 ”即可进入底行模式(last line mode),通常是用来对文件的保存或退出vi编辑的。
在左下角我们可以看到有个“:”出现,则说明你已经进入底行模式(last line mode)
底行模式下的命令使用方法如下表:
末行命令 | 作用 |
---|---|
:w | 保存 |
:q | 退出 |
:wq | 保存后退出 |
:q! | 不保存,强制退出 |
:set nu | 显示行号 |
:set nonu | 取消 显示行号 |
:w [文件名] | 将编辑后的内容保存到另一个文件中(另存为) |
:2,5 w [文件名] | 将第2到5行的内容保存到另一个文件中(指定行另存为) |
:r [文件名] | 输入另一个文件的内容,到光标的下一行 |
总结常用的有如下操作:
1)保存操作(write)
输入:“:w” 保存文件;输入:“:w 路径” 另存为所需的路径。
2)退出(quit) 输入:“:q” 退出文件。
3)保存并退出 输入:“:wq” 保存后退出 。
4)强制退出,之前的操作不保存,或者出现错误退不出时,输入:“:q!” 即可强制退出vim编辑。
说明:如果在底行模式输入了命令,要想清空,按两下ESC,即可清除所有命令。
3、vim打开并编辑C程序
在Ubuntu中,可以用vim直接打开C程序进行编写与编辑,如果没有提前安装,根据提示命令照前文进行安装即可。
命令格式: vim 文件
vim main.c
#打开当前目录下的main.c源文件
上述命令格式打开C程序,光标默认停在首行,如果需要打开C文件且将光标移动到「指定行」,格式为:vim +行数 文件
vim +3 main.c
#打开文件时,光标停在了第三行(默认停在首行)
注意:加号“ +” 是语法格式,不要漏掉
在插入模式编辑好C源程序后,参照上文 “底行模式命令使用表“ ,输入:wq 保存并退出编辑状态。
二、C程序的编译与运行
1、gcc编译器的配置与安装
编译器是一种将高级编程语言(如C、C++、Java等)编写的源代码(Source Code)转换为机器语言(Machine Code)的程序。这个过程包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等步骤。编译器的主要作用是将人类易于理解的代码转换为计算机可以直接执行的代码。
Linux 下使用最广泛的 C/C++ 编译器是 gcc,一般都将gcc作为 Linux 下首选的编译工具。gcc是GNU Compiler Collection的缩写,是一款自由软件的编译器,支持多种编程语言,包括C语言。gcc 仅仅是一个编译器,它将用 C语言编写的程序转换为汇编代码或机器代码以创建可执行程序。没有界面,必须在命令行模式下使用。通过gcc
命令就可以将源文件编译成可执行文件。
在Ubuntu 16.04中,需要先安装gcc编译器。
我们可以通过以下命令在Ubuntu中安装gcc编译器。
sudo apt-get update #更新软件列表
sudo apt-get install gcc #安装gcc
如果已经安装,则会有以下提示:
安装完后,可以通过命令来查看是否安装成功。
gcc --version
2、编译C程序
安装完gcc编译器后,我们就可以对前文编写好的C程序进行编译。
1)编译生成默认文件名
直接编译方式是最简单的生成可执行文件的方法,生成的默认可执行文件名为a.out。
例如,编译目录 wl 下的main.c文件。
cd wl #进入源文件所在的目录
gcc main.c #在 gcc 命令后面紧跟源文件名
执行完成后,查看 wl 目录,会看到多了一个名为 a.out 的文件,即为最终生成的可执行文件。
2)编译生成指定文件名
如果不想使用默认的文件名,那么可以通过-o
选项来自定义文件名。
格式:gcc 源文件名 -o 生成的可执行文件名
例如:
gcc main.c -o main.out #生成的可执行文件名为main.out
因为 Linux 下可执行文件的后缀仅仅只是一种形式上的,因此,可执行文件也可以不带后缀,例如:
gcc main.c -o main #可执行文件省去扩展名,生成的可执行文件名为main。

3)编译输出到其它目录
通过-o
选项也可以将可执行文件输出到其它目录,并不一定非得在当前目录下。
例如:
gcc main.c -o out/main.out
或者
gcc main.c -o ./out/main.out
表示将可执行文件输出到当前目录下的out
目录,并命名为main.out
。
./
表示当前目录,如果不写,默认也是当前目录。
注意:out 目录必须存在,如果不存在,gcc 命令不会自动创建,而是抛出一个错误。
3、运行可执行程序
上文生成了可执行程序a.out、main.out及main,下面运行可执行文件。
1)执行当前目录下可执行文件
执行格式为: ./可执行文件名
./a.out
#或 ./main.out
#或 ./main
“ ./ ”
表示当前目录,整条命令的意思是运行当前目录下的可执行文件程序。
注意:如果不写 “ ./ ”
,Linux 会到系统路径下查找 a.out,而系统路径下显然不存在这个程序,所以会运行失败。
所谓系统路径,就是环境变量指定的路径,我们可以通过修改环境变量添加自己的路径,或者删除某个路径。很多时候,一条 Linux 命令对应一个可执行程序,如果执行命令时没有指明路径,那么就会到系统路径下查找对应的程序。
运行结果如下图:
2)执行其它目录下可执行文件
如果程序在其它目录下,运行程序时需带上目录的路径名字。
例如:执行当前目录中out目录下的main.out文件:
./out/main.out #执行当前目录中out目录下的main.out可执行文件
或者
out/main.out
说明:这个时候加不加 “./ ”
都一样,Linux 能够识别出out
是一个目录,而不是一个命令,它默认会在当前路径下查找该目录,而不是去系统路径下查找,所以不加 “./ ”
也不会出错。
三、C程序的gdb调试
GDB :GNU Debugger,是GNU工程为GNU操作系统开发的调试器,但它的使用不局限于GNU操作系统,GDB可以运行在UNIX、Linux甚至Microsoft Windows。
GDB可以调试C、C++、Objective-C、Pascal、Ada等语言编写的程序;被调试的程序可以跟GDB运行于同一台电脑,也可运行于不同电脑。
使用gdb我们可以设置断点使程序停住,监视或修改程序中变量的值,跟踪代码执行过程。
1、gdb的安装与准备
//终端输入
sudo apt-get install gdb
gdb调试的前提条件与准备:
1)编译时添加调试信息
程序要能被调试,必须包含调试信息。编译程序时,通过gcc的-g选项为程序添加调试信息。
命令如下:
gcc -g main.c -o main
#或者 gcc –g –o main main.c
#这里以main.c为例
2)gdb调试程序,调试时,源文件必须在同一个目录中。
使用命令gdb main 即可进行该程序的调试
2、启动gdb
#终端输入
gdb
3、启动gdb调试
gdb是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本。
gdb可以用来调试C和C++程序,功能不亚于Windows下的许多图形界面的调试工具。
gdb主要帮忙你完成下面四个方面的功能:
1)启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2)可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式、函数等)
3)当程序被停住时,可以检查此时你的程序中所发生的事。
4)动态的改变你程序的执行环境。
下面列出常用的命令说明:
命令 | 功能 | 简写 |
---|---|---|
file | 装入指定的调试程序,也可以在运行gdb的时候加载,两种方法都不会运行程序。例如:gdb ./main | 无 |
help | 查看gdb的帮助信息 | h |
list | 查看程序源代码 | l |
run | 执行当前被调用的程序 | r |
continue | 继续执行,直到下一个断点或程序结束 | c |
next | 单步调试,不进入函数 | n |
step | 单步调试,进入函数 | s |
break | 在代码中设置断点 | b |
info break | 要查看当前设置的所有断点 | i b |
delete breakpoints 断点编号 | 删除断点 | d |
kill | 中止正在调试的程序 | k |
查看变量的值 | p | |
quit | 停止执行调试器 | q |
下面以一个交换两个整型实数的值为例进行分步讲解gdb调试方法及过程。
第一步,使用vim创建程序swap.c
源程序:
#include <stdio.h>
int a,b,temp;
void swap()
{
temp=a;
a=b;
b=temp;
}
int main()
{
a=8;
b=9;
swap();
printf("%d %d\n",a,b);
return 0;
}
第二步,编译调试swap.c
在使用gcc编译源程序的时候必须使用-g选项,以便将调试信息包含在可执行文件中。
gcc -g swap.c -o swap
#生成可执行文件swap,并且带有调试功能
第三步,启动gdb调试
格式:gdb 可执行文件名
4、调试过程
提示:可以按照下列序号进行调试
1)运行程序:(gdb)r,回车
2)查看源程序: (gdb)l,回车
由上图可知,源程序一共16行。
3)设置断点:(gdb) break 11 (行数或者函数名)
在 GDB 中,断点是一个重要的调试策略,断点其实是一个标记,它允许程序在特定点(断点)暂停执行,以便开发者在程序执行过程中检查变量值、调用堆栈、单步执行代码等的状态。
4)开始调试:(gdb)r
5)打印变量值:(gdb)print a (变量名)
由上图a的结果可知,程序执行暂停在11行,11行给a赋的值8并未执行,a的值仍为第2行定义时的初值0。
6)继续执行下一步:(gdb)n
由上图的结果可知,11行已经执行,暂停在12行,因此a的值变成了8,但b的值仍为初值0。
由上图的结果可知,12行已经执行,b的值已从上一步的0变成现在的9。
7)单步调试进入函数:(gdb)s
由上图结果可知,进入函数后再继续单步执行,暂停5行时temp为初值0,执行5行后变为8,下面继续单步调试即可得到最终结果。
8)继续执行,直到跳出函数:(gdb)n
9)打印执行完swap函数后变量的值:
(gdb)print a
(gdb)print b
10)退出调试:(gdb) q