一、用VSCode提升C/C++开发体验
用 VSCode 日常写代码
上一篇文章里,你已经把源代码到二进制文件整条链路亲手走了一遍,代价是 —— 每改一次代码,都要回到终端重新敲一遍 gcc -g -Wall -fexec-charset=GBK hello.c -o hello;想看一个变量的变化,得反复敲 next 和 print。作为程序员,毫无疑问,偷懒是我们的美德 😎 ,那能不能简化这个过程,让我不要重复做这些操作呢?这也是程序员奉行的经典原则之一:DRY原则
说明 · DRY原则
DRY(Don't Repeat Yourself) 出自《程序员修炼之道》—— Every piece of knowledge must have a single, authoritative representation within a system. 注意宾语是 knowledge:它管的是"同一个决定只写一次", 不是"两段代码长得像"。反面的自嘲缩写是 WET(Write Everything Twice)。
所以我们现在也要把从源代码编译成二进制这一整套动作搬进 VSCode。而不是在终端一次次地重复敲命令。VSCode更像一间整理好的书房:工具还在原地(你的电脑上),只是都放到了顺手的位置(VSCode替你调用)。而你要做的第一件事,是搞清楚它到底替你把什么收了起来。

0、安装 VSCode
不管哪个系统,都从 https://code.visualstudio.com/ 下载。区别只在最后那几步:
Windows
页面上点 Download for Windows,下回来的是一个几十兆的安装包,一路 下一步 就能装完。
只有最后一页值得注意一下。安装向导的选择附加任务那一步里,有两个选项,其中一个你现在已经能够理解它是什么意思:
选项 | 勾上之后你会拥有 |
|---|---|
添加到 PATH | 在任何终端里敲 |
提示 · 融会贯通
你掌握了 PATH 的相关知识,以后再见到就能立刻理解。计算机的知识虽不算少,但重复用、常用的知识并没有那么多。
安装完成并将VSCode添加到PATH后,按下 Win + R,输入 powershell 回车,随便进一个文件夹敲:
在终端里执行
code .
如果 VSCode 打开了当前文件夹,说明它生效了,至于为什么生效,为什么系统能够找到code这个命令?你心里有数。
macOS
把下载到的 .zip 解开,将 Visual Studio Code.app 拖进应用程序文件夹,就装完了 —— 没有安装向导,也没有可以勾的选项。
所以那个 code . 命令要手动补上。在 VSCode 里按 Cmd + Shift + P 打开命令面板,输入并运行:
在命令面板里搜索并执行
Shell Command: Install 'code' command in PATH
运行完,终端里的 code . 就和 Windows 上一样可用了。
1、中文界面
VSCode 默认设置是英文。改成中文只需要装一个语言包。
点左侧活动栏最下面那个由四个小方块组成的图标(扩展,快捷键 Ctrl + Shift + X),在搜索框里输入 Chinese,找到 Chinese (Simplified) (简体中文) Language Pack,点 安装。装完右下角会弹出提示,点 Change Language and Restart,界面就是中文的了。
接着还差最关键的一个扩展。在同一个搜索框里输入 C/C++:
注意 · 认准作者是 Microsoft
商店里搜
C/C++会出来一堆名字很像的扩展,只有作者(Publisher)写着 Microsoft 的那个才是官方的。
装完 C/C++,旁边通常还会推荐 C/C++ Extension Pack —— 这是微软给 C/C++ 准备的全家桶,把常用的一整套(C/C++、CMake 支持、主题等)打包在一起。建议一次性装完,省得以后写大一点的作业时一个个补。
问答 · 为什么这两个扩展要分开装?
因为它们管的是两件不同的事:语言包改的是 VSCode 自己的界面文字,C/C++ 扩展负责看懂你的代码(语法高亮、补全、报错、以及后面要用的调试对接)。
所以VSCode本身的功能并不很多,你可以当做是一个更厉害的记事本,之所以它厉害,是因为它可以通过安装各种拓展,使其具备各种能力。
2、让 VSCode 记住那行编译命令:tasks.json
打开VSCode,点击左上角的 文件-->打开文件夹--> 选择你C语言代码存在的那个文件夹 文件夹打开之后,菜单里点 终端 → 配置默认生成任务。VSCode 会列出一串它能找到的编译器,选带 gcc 的那一项:
选择任务时你会看到
C/C++: gcc.exe 生成活动文件
点下去,.vscode/tasks.json 就自动生成好了,内容大概是:
.vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc.exe 生成活动文件",
"command": "C:\\msys64\\ucrt64\\bin\\gcc.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "编译器: gcc"
}
]
}
这个tasks.json文件不是给你读的程序,而是一张写给 VSCode 看的「说明书」 —— 每次让它编译,它就照着这张说明书找到程序、拼好参数、执行命令。所以我们不需要背下这些东西,只要认出它回答的三个问题:让谁去干(command)、怎么干(args)、在哪个文件夹里干(cwd)。
先看 command:它就是编译器在你电脑上安装的位置(上面那个路径是我的电脑上的,你自己电脑上的路径取决于你安装在了哪里)
再看 args:它就是你在上一篇文章中终端编译源文件时敲过的那串东西。

-g 还是那个 -g,-o 还是那个 -o,只不过文件名换成了三个占位符:
占位符 | 它在编译那一刻会变成什么 |
|---|---|
| 你当前打开的那个源文件,也就是 |
| 这个源文件所在的文件夹,也就是 |
| 去掉后缀的文件名,也就是 |
所以 -o "${fileDirname}\\${fileBasenameNoExtension}.exe" 展开之后,正好就是 -o "D:\code\c\hello.exe"。一套任务配置,能编译这个文件夹里所有 .c 文件 —— 换成 world.c,它自动编出 world.exe。这就是占位符的价值。
把展开前后摆在一起看,你会发现它比手敲的那条命令只多了一小段:
两种写法,同一个结果
gcc -g hello.c -o hello
VSCode按照tasks.json 展开后
gcc -fdiagnostics-color=always -g D:\code\c\hello.c -o D:\code\c\hello.exe
多出来的 -fdiagnostics-color=always 只管一件事:让报错带颜色 —— 错误标红、警告标黄,一眼就能看出轻重缓急。不加也照样能编译,只是整屏白字看着费劲。
提示 · 为什么参数要「竖着写」
args里用[ ]把参数一项项排开,和横着写成一整行完全是同一件事:[ "-g", "${file}" ]就等于-g ${file}。 竖着写只有一个好处,但很实在 —— 以后要加参数只要加一行,不用在长长的一行里找该往哪儿插。
说明 · 占位符不只属于 VSCode
${file}、${fileDirname}这类写法你在别的地方也会遇到。(或者说你已经遇到过了,细想一下,PATH是不是就是所谓的占位符?再去翻翻你的windows环境变量设置,然后再体会一下这种占位符用法的好处。)Makefile 的变量、CMake 的
${PROJECT_NAME}、Shell 的$1—— 本质都是同一招:先留个空,等真正执行时再填上。 现在认识它,以后在别的工具里见到就不会陌生。
再把剩下的几个键过一遍。了解即可
键 | 说人话 | 写错或删掉会怎样 |
|---|---|---|
| 这份文件的格式版本,固定写 | 不用改,也别删 |
| 任务列表。 | 没了它,VSCode 读不到任何任务 |
|
| 这正是非认准 Microsoft 那个扩展不可的原因:装成野生扩展,VSCode 根本不认识这个类型 |
| 这个任务的名字, | 名字对不上,按 F5 就提示找不到任务 |
| 让谁去干活 —— | 和 2.6 里 |
| 在哪个文件夹里执行这条命令,相当于先替你 | 影响相对路径怎么解析,指到源文件所在目录最省心 |
| 把 gcc 打印的报错翻译成 VSCode 能标出来的条目 | 编译照样能过,但错误不能点着跳行、也没有红波浪线 |
|
| 少了 |
| 纯备注,只给人看 | 写错不影响运行 |
注意 · 最容易出错的一行:label
"label"是这个任务的名字,后面launch.json会用preLaunchTask去引用它。 引用必须一字不差 —— 包括空格、大小写、C/C++后面的冒号,全都要对上。 手动改过label却忘了同步改launch.json,是“按下 F5 没反应 / 提示找不到任务”这类问题的头号来源。
表里 group 那两个值合起来的效果就是 —— 按 Ctrl + Shift + B 直接跑它,不用再进任何菜单。
顺带说一句,这个文件是跟着文件夹走的:拷给同学、提交进 Git、换台电脑打开都能直接用。你手敲的那些命令,从这里开始不用再重敲第二遍。
最后提醒一件小事:JSON 这个格式本身,有三个「一碰就废」的地方。
新手改这个文件踩的坑,几乎都落在下面三条上。它们不是 VSCode 的规矩,而是 JSON 文件有格式要求:
事故 | 长什么样 | 为什么会废 |
|---|---|---|
逗号 | 每两项之间要有英文逗号,但最后一项后面不能有 | 多一个逗号,整个文件读不出来,任务列表直接空掉 |
中文标点 | 写成中文逗号、中文冒号或中文引号 | JSON 只认英文半角标点,中文标点一律让它读不懂 |
反斜杠 |
| JSON 里 |
现在回到 hello.c,按一下 Ctrl + Shift + B,下方的终端里会刷出编译信息,然后 D:\code\c 里多出 hello.exe。板块四里手敲的那条命令,现在只需要一个快捷键。
备注 · Mac 读者
Mac 上的流程完全一样(终端 → 配置默认生成任务),只是列表里显示的是
C/C++: clang 生成活动文件。 生成的tasks.json里改两个值就够了:"command"填clang,输出文件名末尾不带.exe—— 写成"${fileDirname}/${fileBasenameNoExtension}",注意用的是正斜杠。
如果终端提示 gcc 不是内部或外部命令
说明 VSCode 没能在 PATH 里找到 gcc。最直接的办法是把 command 换成完整路径:
"command": "C:\\mingw64\\bin\\gcc.exe",
注意反斜杠要写成两个(\\)。JSON 里单个 \ 是转义字符,C:\mingw64 这种写法会让 VSCode 读不懂这个文件,整个 tasks.json 直接失效。
换完之后记得把 "detail" 那一行也顺手改掉,它只是给人看的备注,写错了不影响运行。
3、用鼠标打断点:launch.json 与 F5
编译能用了,接着把调试搬进来。打开 hello.c,点左侧活动栏的 运行和调试 图标(或菜单 运行 → 添加配置...),在选择环境里选:
C++ (GDB/LLDB)
再在配置列表里选 C/C++: gcc.exe 生成和调试活动文件。.vscode/launch.json 就生成了:
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++: gcc.exe 生成和调试活动文件",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "C:\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: gcc.exe 生成活动文件"
}
]
}
这个文件里有五个字段需要重点关注:
字段 | 它说的是什么 |
|---|---|
| 要调试的是可执行文件 |
| 用哪个调试器。就是跟着 MinGW 一起装进来的那个 |
| 按 F5 之前,先跑哪个任务。它的值必须和 |
| 是否另开一个黑框窗口。 |
| 是否在 |
备注 · Mac 读者:这个文件里有三处不同
生成配置时同样选
C++ (GDB/LLDB),但填的值不一样:"MIMode"用"lldb"、"miDebuggerPath"用"/usr/bin/lldb"、"program"去掉.exe后缀(写成"${fileDirname}/${fileBasenameNoExtension}")。preLaunchTask则要填 clang 任务的label。

快捷键 | 干什么 |
|---|---|
| 继续运行,直到下一个断点或程序结束 |
| 单步跳过:执行下一行,不钻进函数里面 |
| 单步进入:如果下一行是函数调用,就钻进去 |
| 停止调试,强制结束程序 |
提示 · 这就是 gdb 的图形化版本
你不是换了一套工具,你用的是同一个
gdb:program里的hello.exe是它启动的程序,miDebuggerPath里的gdb.exe是它本体,点红点就是帮你敲了break,按F5就是帮你敲了run,按F10就是next,看变量面板就是帮你敲了
4、Code Runner:方便的代价
在扩展面板里还能找到另一个很受欢迎的扩展:Code Runner。装上之后,编辑器右上角会多出一个 ▶ 按钮,点一下就能跑,快捷键是 Ctrl + Alt + N。
听上去比 Ctrl + Shift + B 还省事。但它的默认行为里藏着两个坑 —— 把它的默认命令展开看:
Code Runner 对 .c 文件默认执行的命令
cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt
注意 · ① 没有
-g。 这条命令编译出来的程序里不含调试信息 —— 上篇文章说过,没有-g,断点就是一句空话。所以用 Code Runner 跑出来的hello.exe,F5是调不动的。② 不管编码。 它也不会替你加
-fexec-charset=GBK,程序里的中文照样可能变成乱码。
所以结论很清楚:Code Runner 适合“我就想快速试两行”,不适合正经写代码。 写作业、做课程设计,老老实实用 Ctrl + Shift + B 加 F5 —— 那套配置里既有 -g,又能打断点,还能一眼看到变量。
5、环境体检表
到这一步,整套环境已经齐了。回头看一眼你走过的路:

最后按下面这张表逐项验一遍。全部打勾,说明你的环境没有任何问题,可以放心开始写代码了:
# | 验收项 | 怎么做 | 期望结果 |
|---|---|---|---|
1 | 编译器就位 | 终端里敲 | 打印出版本号 |
2 | 调试器就位 | 终端里敲 | 打印出版本号 |
3 | VSCode 接进了终端 | 在 | VSCode 打开这个文件夹 |
4 | 项目能识别 | 打开文件夹后,菜单里有 终端 → 配置默认生成任务 | 列表里出现 |
5 | 一键编译 | 打开 | 终端刷出编译信息, |
6 | 程序跑得对 | 在 | 输出 |
7 | 断点能用 | 在 | 程序停在这一行 |
成功 · 到这里,你已经是一个能干活的人了
会安装编译器、会配置PATH让系统找得到安装的软件、会用终端命令计算机执行程序、通过配置文件让编辑器记住了你的命令从而实现一定程度的自动化、调试断点点一下就生效。 剩下的事只有一件 —— 开始写代码。
结语 · 环境配好之后,该往哪走
摘要 · 你真正拿到手的东西
不是“会装 VSCode”,而是知道每一步在发生什么。 别人按那个小三角按钮的时候只知道“跑起来了”;你知道那背后是
gcc在做预处理、编译、汇编、链接,知道-g决定断点能不能生效,知道 PATH 是系统手里的那份通讯录,知道 VSCode 只是把你敲过的命令记进了两个 JSON 文件。 环境配置会随版本变化,这套原理不会。
接下来该往哪走?
不要急着换 IDE。 你以后一定会听到 VS / CLion / Vim 的名字,也可能被人劝“换一个更好用”。但是 —— 工具切换是几分钟的事,看懂编译、链接、调试这三件事才是值钱的。熟知原理才能以不变应万变,换任何工具都只是熟悉一下界面,况且VSCode大多数情况下已经足够好用。
先把命令行用熟。
-o定输出名、-g带调试信息、-Wall开警告、-std=定标准 —— 这四个参数够你用很久。更重要的是:服务器上不会有按钮给你点,命令行是你唯一的操作方式。把调试器用熟。 断点、单步、查看变量,这三件套能解决你未来 80% 的“为什么结果不对”。学会先怀疑自己,再让程序停下来告诉你答案,而不是盯着代码发呆。
下一步学 Makefile,再进阶 CMake。 现在你只有一个
hello.c,手敲一条命令当然没问题。等当你需要编写三个.c文件互相调用的时候,你就该让机器替你记住“先编哪个、再链哪个”了 —— 这正是 Makefile 在干的事。遇到报错,原样复制去搜。 不要用自己话转述,报错原文里的文件名、行号、错误码都是关键词。另外养成一个习惯:永远先看第一条 error,后面的错误常常是它的连锁反应。
动手才是真的学。 看十遍教程不如自己写一遍。可以从洛谷、力扣、牛客上找最简单的入门题开始,也可以把课本上的例题自己敲一遍再改几个数字试试。卡住的时候先别急着问,先自己调一次断点。
现在就可以学 Git。 不用等写大项目。哪怕只有一个
hello.c,也可以建一个仓库 —— 往后你会发现“能随时回到昨天那个能跑的版本”是一件多让人安心的事。
一张图看清接下来这几步的关系:
接下来这几步: ① 本文完成(环境全部跑通)→ ② 刷基础题(洛谷 / 力扣 / 牛客)→ ③ 读教材(《C Primer Plus》)→ ④ 学 Git(把代码管起来)→ ⑤ 学 Makefile(多文件自动构建)→ ⑥ 进阶 CMake(工程级项目)
顺序不必严格照搬 —— 先学 Git 再刷题也完全可以。但有一点值得记住:每一步都踩在已经跑通的环境上往前半步,而不是推倒重来。
祝你的第一个程序顺利跑通。 从今天起,我希望读者能够记住从小开始就耳熟能详的那句话:“基础不牢,地动山摇”。