之前我写了很多 C++ 语言和数据结构的知识,也写过 Linux 的文件权限。今天,我要把目光投向程序员的三个核心工具:编辑器、编译器和调试器。在 Linux 世界里,最经典的组合就是 Vim、GCC 和 GDB。
无论是刚接触 Linux 开发,还是想从 IDE 转向更轻量、更灵活的命令行开发环境,这三个工具都值得花时间熟练。它们虽然需要一定的学习曲线,但带来的效率提升会是几何级的。
第一部分:Vim —— 强大的终端编辑器
Vim(Vi IMproved)是 Linux 下最流行的文本编辑器之一。它的特点是多模式编辑,能让手不离开键盘,编程速度快得飞起。但初学者最大的困惑就是:进去之后不知道怎么输入文字,也不知道怎么退出。
1.1 模式:Vim 的灵魂
Vim 有三种基本模式:
| 普通模式(Normal) | 浏览、复制、粘贴、删除、移动 | 启动 Vim 或按 Esc |
| 插入模式(Insert) | 像普通编辑器一样输入文字 | 在普通模式下按 i(光标前插入)或 a(光标后插入) |
| 命令行模式(Command) | 保存、退出、搜索、设置 | 在普通模式下按 : |
记住一条铁律:任何时候按 Esc 都会回到普通模式。不知道自己在哪就狂按 Esc,然后重新操作。
1.2 生存指南:打开、编辑、保存、退出
打开文件:
vim hello.cpp
进入后,你处在普通模式。按 i 进入插入模式,然后可以输入代码。
输入完后:
按 Esc 回到普通模式。
输入 :w 然后回车 → 保存(write)。
输入 :q 然后回车 → 退出(quit)。
或者合起来 :wq → 保存并退出。
如果改乱了想不保存退出::q! → 强制退出,不保存。
1.3 常用移动命令(在普通模式下)
| h / j / k / l | 左 / 下 / 上 / 右(替代方向键) |
| w / b | 跳到下一个单词开头 / 上一个单词开头 |
| 0 / ^ / $ | 移到行首 / 第一个非空字符 / 行尾 |
| gg / G | 跳到文件开头 / 文件末尾 |
| Ctrl+f / Ctrl+b | 向下翻页 / 向上翻页 |
| :n 然后回车 | 跳到第 n 行 |
1.4 常用编辑命令(普通模式)
| x | 删除光标所在字符 |
| dd | 删除(剪切)一行 |
| yy | 复制一行 |
| p | 粘贴在光标后 |
| u | 撤销 |
| Ctrl+r | 重做 |
| r + 字符 | 替换光标所在字符 |
| >> / << | 增加 / 减少缩进 |
1.5 搜索与替换(命令行模式)
-
搜索:/关键词 回车,然后 n 下一个,N 上一个。
-
替换::s/旧/新/g → 替换当前行所有。
:%s/旧/新/g → 替换全文件所有。
加上 c 可以确认,如 :%s/旧/新/gc。
1.6 可视化模式(多选)
在普通模式下按 v 进入字符选择,V 行选择,Ctrl+v 块选择。选择后可以配合 d(删除)、y(复制)、>(缩进)等。
1.7 分屏与切换
-
水平分屏 :split 文件名 或 :sp
-
垂直分屏 :vsplit 文件名 或 :vsp
-
在窗口间切换 Ctrl+w 然后 h/j/k/l
1.8 配置 Vim
在你的家目录创建 .vimrc 文件可以保存常用设置:
syntax on " 语法高亮
set number " 显示行号
set tabstop=4 " Tab 宽度为4
set shiftwidth=4 " 自动缩进宽度
set expandtab " 将 Tab 转为空格
set autoindent " 自动缩进
set mouse=a " 启用鼠标
每次启动 Vim 都会自动加载这些配置。
第二部分:GCC —— C/C++ 编译器
GCC(GNU Compiler Collection)是 Linux 下最标准的 C 和 C++ 编译器。我们常常直接使用 g++ 命令来编译 C++ 程序。
2.1 从源码到可执行文件
一个最简单的编译:
g++ hello.cpp -o hello
-
hello.cpp:源文件。
-
-o hello:指定输出文件名为 hello,不写默认是 a.out。
实际上编译分为四个阶段:预处理、编译、汇编、链接。g++ 一条命令走完全部。
2.2 常用编译选项
| -std=c++11 | 指定 C++ 标准,可用 c++14、c++17 等 |
| -Wall | 打开几乎所有常用警告(强烈建议) |
| -Wextra | 额外警告 |
| -Werror | 把警告当作错误处理 |
| -g | 生成调试信息,配合 GDB 使用 |
| -O0 / -O1 / -O2 / -O3 | 优化级别,0 不优化,3 激进优化 |
| -I 目录 | 添加头文件搜索路径 |
| -L 目录 | 添加库文件搜索路径 |
| -l 库名 | 链接某个库,如 -lpthread(pthread 库) |
| -c | 只编译不链接,生成 .o 目标文件 |
| -D 宏 | 定义宏,如 -DDEBUG |
示例:开启所有警告、使用 C++17、调试模式、优化 O2
g++ -std=c++17 -Wall -Wextra -Werror -g -O2 main.cpp -o main
2.3 多文件编译
假如项目有 main.cpp、utils.cpp、utils.h:
# 一起编译
g++ main.cpp utils.cpp -o myapp
更规范的方式:先编译每个 .cpp 成 .o,再链接:
g++ -c main.cpp -o main.o
g++ -c utils.cpp -o utils.o
g++ main.o utils.o -o myapp
为什么这样?因为当你只修改了 main.cpp 时,只需要重新编译 main.o 再链接,而无需重新编译 utils.cpp,这在大型项目中能节省大量时间。通常配合 Makefile 使用。
2.4 生成和使用静态库 / 动态库
静态库(.a):
g++ -c utils.cpp -o utils.o
ar rcs libutils.a utils.o # 创建静态库
g++ main.cpp -L. -lutils -o myapp # -L. 当前目录 -lutils 链接 libutils.a
动态库(.so):
g++ -fPIC -c utils.cpp -o utils.o
g++ -shared utils.o -o libutils.so
g++ main.cpp -L. -lutils -o myapp
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH # 运行前加入库路径
./myapp
第三部分:GDB —— GNU 调试器
GDB 是一个命令行的调试器,可以用来设置断点、单步执行、查看变量值、分析崩溃原因等。掌握它,你就不必再靠满屏的 cout 来定位错误了。
3.1 用调试信息编译
必须使用 -g 选项编译,且建议关闭优化(-O0),否则变量可能被优化掉或乱序执行。
g++ -g -O0 main.cpp -o main
3.2 启动 GDB
gdb ./main
你将进入 (gdb) 提示符。下面是核心命令一览。
3.3 核心命令
| run | r | 开始运行程序(可带参数,如 run arg1 arg2) |
| break 函数名 | b main | 在函数入口设置断点 |
| break 行号 | b 10 | 在第10行设置断点 |
| break 文件名:行号 | b utils.cpp:5 | 在指定文件的某行设断点 |
| info breakpoints | i b | 查看所有断点 |
| delete 断点号 | d 1 | 删除1号断点 |
| continue | c | 继续执行到下一个断点 |
| step | s | 单步执行,会进入函数内部 |
| next | n | 单步执行,不进入函数内部(跳过函数) |
| finish | fin | 执行完当前函数并返回 |
| print 表达式 | p x | 打印变量 x 的值 |
| print *指针 | p *ptr | 打印指针指向的对象 |
| display 表达式 | disp x | 每次单步都自动显示 x 的值 |
| list | l | 显示当前位置周围的源代码 |
| backtrace | bt | 显示函数调用栈(崩溃时必备) |
| frame 编号 | f 0 | 切换到调用栈中的某一层 |
| quit | q | 退出 GDB |
3.4 实战示例
假设有以下程序 fact.cpp:
#include <iostream>
int factorial(int n) {
if (n == 0) return 1;
return n * factorial(n – 1);
}
int main() {
int result = factorial(5);
std::cout << result << std::endl;
return 0;
}
编译并调试:
g++ -g -O0 fact.cpp -o fact
gdb ./fact
在 GDB 中:
(gdb) break main // 在 main 入口断点
(gdb) run // 运行,停在 main
(gdb) step // 单步,会进入 factorial 函数
(gdb) print n // 打印参数 n 的值
(gdb) backtrace // 查看调用栈
(gdb) continue // 继续执行
(gdb) quit // 退出
3.5 调试已崩溃的程序(core dump)
当程序崩溃(段错误等),可以开启 core dump 生成,然后事后调试。
开启 core dump(ulimit):
ulimit -c unlimited
运行程序崩溃后,会生成 core 文件,然后:
gdb ./main core
(gdb) bt # 直接查看崩溃时的调用栈,非常高效
第四部分:三者配合的经典工作流
一个典型的 C++ 开发流程:
使用 Vim 编写源代码,vim main.cpp。
编译并开启警告和调试信息:g++ -std=c++17 -Wall -g -O0 main.cpp -o main。
运行:./main。
如果有段错误或逻辑错误,启动 GDB:gdb ./main,设断点,运行,单步,查看变量。
修改代码,重复以上。
熟练之后,再加上 Makefile 或,就能形成一套轻量、全能的 Linux 开发环境。
小结
-
Vim:多模式编辑器,掌握基本移动、编辑、保存退出,然后逐步学习高级命令。
-
GCC:编译驱动,常用选项 -std、-Wall、-g、-O,理解多文件编译和库链接。
-
GDB:命令行调试器,核心是断点(break)、运行(run)、查看(print)、单步(next/step)和调用栈(bt)。
这三个工具是 Linux 编程的基石,也许一开始会感觉命令行不够友好,但当你投入时间去熟练,它们会回报你以极致的控制力和灵活性。
网硕互联帮助中心







评论前必须登录!
注册