mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
1859 字
8 分钟
Linux 网络编程(23):Linux 编辑、编译与调试——Vim、GCC 与 GDB

Linux 编辑、编译与调试:Vim、GCC 与 GDB#

本节学习 Linux 环境下完整的代码开发流程:使用 Vim 创建和编辑源文件,使用 GCC 编译单文件或多文件程序,再通过 GDB 进行源码级调试。

重点包括 Vim 的三种工作模式和常用操作、GCC 的输出文件、头文件搜索路径与宏定义选项,以及 GDB 的单步执行、变量观察和断点管理。

一、Vim 编辑器#

1.1 Vim 的作用#

使用 vi 命令进入 Vim:

vi 文件名

它有两种常见情况:

  • 文件已经存在:打开并编辑该文件;
  • 文件不存在:先进入一个新的空缓冲区,保存后才会真正创建文件。

例如:

vi aa

如果 aa 原本不存在:

  • 使用 :wq 保存退出后,磁盘上会出现 aa
  • 使用 :q! 不保存退出后,aa 不会被创建。

1.2 Vim 的三种工作模式#

Vim 的操作关键在于先判断当前处于哪一种模式。

模式作用进入方式
命令模式(普通模式)删除、复制、粘贴、撤销、查找等打开 Vim 后默认进入;插入模式下按 Esc 返回
插入模式输入和修改文件内容命令模式下按小写 i
末行模式保存、退出、分屏等命令模式下按 :

1.3 保存与退出#

命令含义适用情况
:wq保存并退出内容需要保留
:q!强制退出,不保存修改放弃本次修改
:q直接退出文件没有发生修改时

其中:

  • w 表示 write(写入、保存);
  • q 表示 quit(退出);
  • ! 表示强制执行。

即使先输入了一些内容,后来又手动删回原样,Vim 仍可能认为文件被修改过。此时 :q 不能退出,需要使用 :wq:q!

1.4 命令模式下的常用操作#

1.4.1 删除行#

dd

删除光标当前所在的一行。

Ndd

从光标所在行开始,向下删除 N 行。

示例:

5dd

表示从当前行开始向下删除 5 行。

1.4.2 撤销与反撤销#

命令作用
u撤销上一步操作,连续按可逐步向前撤销
U一次性撤销当前行此前所做的修改
Ctrl+R反撤销,即恢复刚刚撤销的操作

1.4.3 复制与粘贴#

yy

复制当前行。

Nyy

从当前行开始向下复制 N 行。

示例:

5yy

表示复制从当前行开始的 5 行。

复制后,把光标移动到目标位置,再按:

p

内容会粘贴到光标所在行的下一行。

1.4.4 查找字符串#

/字符串

输入后按回车,Vim 会查找并高亮匹配内容。

n

跳到下一个匹配位置。查找到文件末尾后,会从文件开头继续循环查找。

1.4.5 查看函数帮助#

先把光标移动到函数名上,再执行:

命令作用
K按默认手册章节查看帮助
2K查看第 2 章系统调用手册
3K查看第 3 章库函数手册

进入帮助页面后,按 q 退出帮助。

1.4.6 整体格式化代码#

gg=G

按键含义:

  • gg:移动到文件开头;
  • =:执行缩进格式化;
  • G:范围到文件结尾。

1.5 Vim 分屏#

实际项目通常包含多个源文件和头文件。分屏可以在同一个 Vim 会话中同时查看或编辑多个文件。

1.5.1 左右分屏#

:vsp 文件名

1.5.2 上下分屏#

:sp 文件名

1.5.3 在多个窗口之间切换#

Ctrl+W,然后再按 W

1.5.4 分屏中的保存和退出#

光标当前位于哪个窗口,插入、保存和退出命令就作用于哪个文件。

二、GCC 编译#

2.1 从源文件生成可执行文件#

gcc 源文件 -o 目标文件

例如:

gcc main.c -o myapp

含义:

  • gcc:调用 GCC 编译器;
  • main.c:要编译的源文件;
  • -o myapp:把输出文件命名为 myapp

运行当前目录中的程序:

./myapp

Linux 不会默认到当前目录查找程序,所以运行当前目录中的可执行文件时要写 ./

2.2 不指定输出文件名#

如果只写:

gcc main.c

GCC 会生成默认名称:

a.out

2.3 查看 GCC 版本#

gcc -v

2.4 编译多个源文件#

当一个项目由多个 .c 文件组成时,需要把参与编译的源文件全部列出。

进入 src 目录后,可编译多个源文件:

gcc main.c add.c mul.c -I../include -o myapp

2.5 使用 -I 指定头文件搜索路径#

如果头文件与源文件不在同一目录,编译器默认可能找不到头文件,需要使用大写 -I 指定头文件目录:

-I头文件目录

示例:

-I../include

2.6 使用 -Wall 显示更多警告#

gcc main.c -Wall -o myapp

2.7 使用 -D 在编译时定义宏#

示例:

int a = 0;
#ifdef DEBUG
a += 100;
#else
a += 200;
#endif

不定义 DEBUG 宏时:

gcc main.c -o myapp

程序进入 #else 分支,a 的结果为 200。

在编译时定义 DEBUG 宏:

gcc main.c -DDEBUG -o myapp

程序进入 #ifdef DEBUG 分支,a 的结果为 100。

三、GDB 调试#

3.1 为什么编译时要加 -g#

若想进行源码级调试,编译时要加入小写 -g

gcc -g qwpj.c -o qwpj2

3.2 进入 GDB#

gdb 可执行文件名

例如:

gdb qwpj2

3.3 查看源代码:list#

缩写:

l

作用:在 GDB 中显示源代码,一次显示大约 10 行。

还可以指定行号:

l 1
l 23

用于查看指定行附近的源代码。如果行号超出源码范围,GDB 会给出范围提示。

3.4 开始调试:startrun#

start#

start

从头开始调试,并默认停在 main 函数的第一条可执行语句处。

GDB 当前显示的代码行表示“下一条即将执行的语句”,不是“已经执行完的语句”。

run#

缩写:

r

作用:从程序开头运行。

  • 有断点:停在遇到的第一个断点处;
  • 没有断点:直接运行到程序结束。

对比:

命令开始后停在哪里
start默认停在 main 的第一条可执行语句
run / r停在第一个断点;没有断点则运行到结束

3.5 单步调试:stepnext#

单步进入函数#

缩写:

s

如果当前语句调用了函数,step 会进入该函数内部继续调试。

单步越过函数#

缩写:

n

如果当前语句调用了函数,next 会把函数调用作为一整步执行,不进入函数内部,然后停在下一行。

对比:

命令遇到函数调用时
step / s进入函数内部
next / n不进入函数,执行后停在下一行

3.6 查看变量#

单次打印变量#

print 变量名

缩写:

p 变量名

它只打印变量当前这一刻的值。

持续显示变量#

display 变量名

之后每执行一步,GDB 都会自动显示该变量的新值。

可以同时 display 多个变量,GDB 会为每个持续显示项分配编号。

取消持续显示#

undisplay 编号

例如:

undisplay 2

注意:undisplay 后面写的是显示项编号,不是变量名。

3.7 设置断点#

GDB 可以按行号或函数名设置断点。

按行号设置断点#

break 9

缩写:

b 9

按函数名设置断点#

break 函数名

缩写:

b 函数名

3.8 查看断点信息#

info breakpoints

3.9 继续运行到下一个断点#

continue

缩写:

c

3.10 禁用与重新启用断点#

禁用断点:

disable 断点编号

重新启用断点:

enable 断点编号

3.11 退出 GDB#

quit

缩写:

q
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Linux 网络编程(23):Linux 编辑、编译与调试——Vim、GCC 与 GDB
https://joyanblog.com/posts/linux-network-programming-23-vim-gcc-gdb/
作者
Joyan
发布于
2026-08-16
许可协议
CC BY-NC-SA 4.0
相关文章 智能推荐

目录