一、用VSCode提升C/C++开发体验
用 VSCode 日常写代码
上一篇文章里,你已经把源代码到二进制文件整条链路亲手走了一遍,代价是 —— 每改一次代码,都要回到终端重新敲一遍 gcc -g -Wall -fexec-charset=GBK hello.c -o hello;想看一个变量的变化,得反复敲 next 和 print。作为程序员,毫无疑问,偷懒是我们的美德 😎 ,那能不能简化这个过程,让我不要重复做这些操作呢?这也是程序员奉行的经典原则之一: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/ 下载。区别只在最后那几步:
页面上点 Download for Windows,下回来的是一个几十兆的安装包,一路 下一步 就能装完。
只有最后一页值得注意一下。安装向导的选择附加任务那一步里,有两个选项,其中一个你现在已经能够理解它是什么意思:
| 选项 | 勾上之后你会拥有 |
|---|---|
| 添加到 PATH | 在任何终端里敲 code .,就能用 VSCode 打开当前文件夹 |
你掌握了 PATH 的相关知识,以后再见到就能立刻理解。计算机的知识虽不算少,但重复用、常用的知识并没有那么多。
安装完成并将VSCode添加到PATH后,按下 Win + R,输入 powershell 回车,随便进一个文件夹敲:
|
|
如果 VSCode 打开了当前文件夹,说明它生效了,至于为什么生效,为什么系统能够找到code这个命令?你心里有数。
把下载到的 .zip 解开,将 Visual Studio Code.app 拖进应用程序文件夹,就装完了 —— 没有安装向导,也没有可以勾的选项。
所以那个 code . 命令要手动补上。在 VSCode 里按 Cmd + Shift + P 打开命令面板,输入并运行:
|
|
运行完,终端里的 code . 就和 Windows 上一样可用了。
1、中文界面
VSCode 默认设置是英文。改成中文只需要装一个语言包。
点左侧活动栏最下面那个由四个小方块组成的图标(扩展,快捷键 Ctrl + Shift + X),在搜索框里输入 Chinese,找到 Chinese (Simplified) (简体中文) Language Pack,点 安装。装完右下角会弹出提示,点 Change Language and Restart,界面就是中文的了。
接着还差最关键的一个扩展。在同一个搜索框里输入 C/C++:
商店里搜 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 的那一项:
|
|
点下去,.vscode/tasks.json 就自动生成好了,内容大概是:
这个tasks.json文件不是给你读的程序,而是一张写给 VSCode 看的「说明书」 —— 每次让它编译,它就照着这张说明书找到程序、拼好参数、执行命令。所以我们不需要背下这些东西,只要认出它回答的三个问题:让谁去干(command)、怎么干(args)、在哪个文件夹里干(cwd)。
先看 command:它就是编译器在你电脑上安装的位置(上面那个路径是我的电脑上的,你自己电脑上的路径取决于你安装在了哪里)
再看 args:它就是你在上一篇文章中终端编译源文件时敲过的那串东西。

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

| 快捷键 | 干什么 |
|---|---|
F5 |
继续运行,直到下一个断点或程序结束 |
F10 |
单步跳过:执行下一行,不钻进函数里面 |
F11 |
单步进入:如果下一行是函数调用,就钻进去 |
Shift + F5 |
停止调试,强制结束程序 |
你不是换了一套工具,你用的是同一个 gdb:program 里的 hello.exe 是它启动的程序,miDebuggerPath 里的 gdb.exe 是它本体,点红点就是帮你敲了 break,按 F5 就是帮你敲了 run,按 F10 就是 next,看变量面板就是帮你敲了 print。
唯一的区别:命令它替你敲了,眼睛替你省了。
4、Code Runner:方便的代价
在扩展面板里还能找到另一个很受欢迎的扩展:Code Runner。装上之后,编辑器右上角会多出一个 按钮,点一下就能跑,快捷键是 Ctrl + Alt + N。
听上去比 Ctrl + Shift + B 还省事。但它的默认行为里藏着两个坑 —— 把它的默认命令展开看:
|
|
警告
① 没有 -g。 这条命令编译出来的程序里不含调试信息 —— 上篇文章说过,没有 -g,断点就是一句空话。所以用 Code Runner 跑出来的 hello.exe,F5 是调不动的。
② 不管编码。 它也不会替你加 -fexec-charset=GBK,程序里的中文照样可能变成乱码。
所以结论很清楚:Code Runner 适合“我就想快速试两行”,不适合正经写代码。 写作业、做课程设计,老老实实用 Ctrl + Shift + B 加 F5 —— 那套配置里既有 -g,又能打断点,还能一眼看到变量。
5、环境体检表
到这一步,整套环境已经齐了。回头看一眼你走过的路:
最后按下面这张表逐项验一遍。全部打勾,说明你的环境没有任何问题,可以放心开始写代码了:
| # | 验收项 | 怎么做 | 期望结果 |
|---|---|---|---|
| 1 | 编译器就位 | 终端里敲 gcc --version |
打印出版本号 |
| 2 | 调试器就位 | 终端里敲 gdb --version |
打印出版本号 |
| 3 | VSCode 接进了终端 | 在 D:\code\c 里敲 code . |
VSCode 打开这个文件夹 |
| 4 | 项目能识别 | 打开文件夹后,菜单里有 终端 → 配置默认生成任务 | 列表里出现 C/C++: gcc.exe 生成活动文件 |
| 5 | 一键编译 | 打开 hello.c,按 Ctrl + Shift + B |
终端刷出编译信息,D:\code\c 里出现 hello.exe |
| 6 | 程序跑得对 | 在 D:\code\c 里运行 .\hello |
输出 "Hello, C!" |
| 7 | 断点能用 | 在 printf("Hello, C!"); 行号左边点一下,按 F5 |
程序停在这一行 |
会安装编译器、会配置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,也可以建一个仓库 —— 往后你会发现“能随时回到昨天那个能跑的版本”是一件多让人安心的事。
一张图看清接下来这几步的关系:
graph LR A["本文完成
环境全部跑通"] --> B["刷基础题
洛谷 / 力扣 / 牛客"] B --> C["读教材
《C Primer Plus》"] C --> D["学 Git
把代码管起来"] D --> E["学 Makefile
多文件自动构建"] E --> F["进阶 CMake
工程级项目"]
graph LR A["本文完成
环境全部跑通"] --> B["刷基础题
洛谷 / 力扣 / 牛客"] B --> C["读教材
《C Primer Plus》"] C --> D["学 Git
把代码管起来"] D --> E["学 Makefile
多文件自动构建"] E --> F["进阶 CMake
工程级项目"]
graph LR A["本文完成
环境全部跑通"] --> B["刷基础题
洛谷 / 力扣 / 牛客"] B --> C["读教材
《C Primer Plus》"] C --> D["学 Git
把代码管起来"] D --> E["学 Makefile
多文件自动构建"] E --> F["进阶 CMake
工程级项目"]
|
|
顺序不必严格照搬 —— 先学 Git 再刷题也完全可以。但有一点值得记住:每一步都踩在已经跑通的环境上往前半步,而不是推倒重来。
祝你的第一个程序顺利跑通。 从今天起,我希望读者能够记住从小开始就耳熟能详的那句话:“基础不牢,地动山摇”。