如何在Linux系统下进行C语言程序的编写和debug测试
一、vim的基本操作
1. 模式
vim通常会用到三个模式,分别是普通模式、插入模式和命令行模式:
普通模式就是使用vim打开文件后默认进入的模式,此时并不能直接进行文件的编写工作,需要一些特定的指令来进行删除、复制等操作。
在普通模式下按i键即可进入插入模式,这个时候就可以正常编写文件了,要退回到普通模式按Esc键。
要从普通模式进入到命令行模式则使用Shift+;键,就可以进入命令行模式,再使用Esc就可以退回到普通模式。
2. 普通模式下的一些操作
2.1移动光标
移动光标一般可以使用方向键,但是也可以使用HJKL这四个按键分别代表左下上右。
当需要移动的比较远时还有其他方法:
- w/W跳到下一个单词开头
- b/B跳到上一个单词开头
- e/E跳到单词末尾
- 0跳到行首
- ^跳到行首第一个非空白字符
- &跳到行尾
- gg跳到第一行行首
- G跳到最后一行行首
- nG跳到第n行(4G就是第4行)
2.2删除、复制和粘贴
删除一般可以进入insert模式进行,要删除一整行可以使用dd/ndd(删除一行/删除n行),而dd并不是单纯的删除,本质上是剪切,因此使用dd删除的内容可以使用p粘贴出来。而如果只是想单纯的复制,则可以使用yy/nyy。要撤销操作则使用u,而如果撤销过多了要恢复撤销的内容则使用ctrl+r。
使用ZZ就可以保存并退出了。
普通模式还有一些其他操作,这里就不做更多介绍了,以上这些操作足够日常使用。
3. 命令行模式下一些常用命令
- w:保存
- w filename:保存为filename
- q:退出
- q!:强制退出
- wq或x:保存并退出
以上是vim的一些常用的基本操作,还有一些组合键可以在使用的过程中按需要去学习这里不做更多介绍。另外,vim还可以进行一些设置,用来配置成自己习惯的样子,这里也不做更多介绍,有兴趣可以自行搜索配置。
二、关于gcc进行编译的模式选择
最简单的用法就是,在使用vim编写了一个c语言程序以后,直接gcc这个文件,如果程序编写没有问题的话,就会生成一个a.out的可执行文件,这时候只需要在命令行输入./a.out就能运行我们编写好的程序。
但是众所周知,从代码到计算机能识别的二进制语言需要经过,预处理、编译、汇编和链接这几个阶段,如果我们想要看其中一个阶段的中间文件应该怎么处理呢?gcc给了一个方案,以test.c为例子进行示范:
通过-E,-S,-c三个后缀,再用-o命名生成的过程文件,我们就可以得到.i,.s,.o以及可执行程序,而 -E,-S,-c分别代表预处理、编译、汇编,上面程序最后的gcc test.o -o test,就是对二进制进行链接。由于这里使用的是动态库,如果要使用静态库则需要:
gcc 源文件.c -o 输出程序 -L库目录 -l库名
进行链接。
三、gdb的使用
在vim编写程序时,并不能像在windows操作系统中的vs等软件那样随时写随时进行,但是调试仍然是必要的,因此需要gdb这个工具来帮助我们进行调试。
在使用gdb之前,我们需要知道,gcc默认生成的可执行程序是release版本的,并不能拿来进行debug。因此,我们需要手动修改gcc生产的可执行程序的版本:gcc -g -o test test.c
也就是多加一个-g的后缀,这样生成的test就可以用gdb运行。
当我们gdb test以后看到这么一大串,最后跟着一个(gdb)的指令行时,我们就可以输入命令进行调试了。
3.1 gdb的常用操作
运行程序:
run
或r
: 从头开始运行程序。run <arg1> <arg2> ...
: 带命令行参数运行程序。
设置断点: 程序执行到断点处会暂停。
break <location>
或b <location>
: 在指定位置设置断点。b main
: 在main
函数入口处设置断点 (最常用)。b file.c:42
: 在file.c
文件的第 42 行设置断点。b function_name
: 在名为function_name
的函数入口处设置断点。
info breakpoints
或i b
: 列出所有已设置的断点及其编号。delete <breakpoint-number>
或d <breakpoint-number>
: 删除指定编号的断点。(这里的breakpoint-number就是断点编号,可以通过i b查看)delete
: 删除所有断点。disable <breakpoint-number>
: 禁用断点 (不删除)。enable <breakpoint-number>
: 启用被禁用的断点。
控制程序执行 (当程序暂停在断点后):
continue
或c
: 继续运行程序,直到遇到下一个断点、信号或程序结束。next
或n
: 单步执行 (Step Over)。执行当前行的代码,如果该行包含函数调用,则不会进入该函数内部,而是把整个函数当作一步执行完。step
或s
: 单步进入 (Step Into)。执行当前行的代码,如果该行包含函数调用,则进入该函数的第一行代码暂停。finish
或fin
: 执行完当前函数 (Step Out)。继续执行,直到当前函数返回,然后在调用该函数的地方暂停。until
或u
: 继续运行直到退出当前循环或到达指定行号 (例如u 50
运行到当前文件的第 50 行)。在循环中特别有用,可以快速跳出循环。
检查程序状态:
print <expression>
或p <expression>
: 打印变量或表达式的值。p variable
: 打印变量variable
的当前值。p *pointer
: 解引用指针,打印指针指向的值。p array[5]
: 打印数组元素。p function_call(arg)
: 调用函数并打印其返回值 (谨慎使用,可能改变程序状态!)。p/x variable
: 以十六进制格式打印变量。p/d variable
: 以十进制格式打印变量 (默认)。p/c variable
: 以字符格式打印变量。
display <expression>
: 每次程序暂停时自动打印指定表达式的值。info locals
或i locals
: 打印当前栈帧 (函数) 的所有局部变量。info args
或i args
: 打印当前函数的参数值。backtrace
或bt
: 打印调用堆栈。显示程序是如何执行到当前位置的 (函数调用链)。在程序崩溃或暂停时,这是最重要的命令之一,用于定位问题根源。frame <frame-number>
或f <frame-number>
: 切换到调用栈中的指定栈帧 (结合bt
查看编号)。然后可以使用info locals
,info args
,print
等命令查看该栈帧的上下文。list
或l
: 显示当前暂停位置附近的源代码。l <line-number>
: 显示指定行附近的源代码。l <function-name>
: 显示指定函数附近的源代码。
以上这些操作暂时记不下来很正常,需要在使用中慢慢增加熟练度,gdb还有一些指令这里暂时不做介绍,最好是在调试过程中根据需要进行针对性的学习。
最后,离开gdb只需要q,就可以。
通过vim编写.c文件,再使用gcc对文件进行编译,最后再使用gdb对文件进行调试,最终就可以完成在Linux中进行C语言程序的编写,对初学者来说每个软件的操作都很复杂,相比windows的图形交互门槛更高,但是Linux是程序开发中绕不过去的坎,要克服这个困难还是要像学习C语言以及C++时一样,多加练习。