Windows × VSCode 打造愉快的单文件 C/C++ 开发体验

好像这个应该在 2018 年就写的……

最近有不少大一小朋友们又开始了饱受 Dev C++ 折磨的 C 语言课程。有一部分先进的小朋友选择使用 Visual Studio 进行编程,不过还是在 scanfscanf_s 之间挣扎了一段时间。如果是纯粹为了 C 语言上机题,完全没必要大动干戈使用完整的 VS(至于 Dev C++?赶紧把这玩意儿丢进历史的垃圾堆吧),可以选择相对轻量的 Visual Studio Code。

其实我自己是在 2018 年大一的时候就已经开始在用 VSCode 了。不过最近有小朋友们问到了这个事情,就开一篇博客写一些吧(毕竟最近也没什么写的)

话不多说,行くぞ!

先决条件

本文旨在讨论 Windows 环境下配置 VSCode 的开发环境,因此当然要先装好 VSCode 啦。

编译器的选择上,本文采用 TDM-GCC。选择它的原因是因为 64 位的 TDM-GCC 可以选择编译出 32 位还是 64 位的可执行文件,同时它的版本相对来说还算新的。在官网上下载时注意选择 64+32-bit 版本的。

如果追求更新的 GCC 版本,可以考虑使用 msys2。另外,极其不建议使用 MinGW-w64,它的 GCC 相对来说较旧(最后一个版本只到 8.1.0),而 8.1.0 又存在一个严重的 Bug。

编译器安装的时候,注意勾选添加 PATH 环境变量。完成之后,打开命令行界面,键入 gcc --version 然后回车。如果环境变量正确配置,将会看到如下图所示的输出。

安装好 VSCode 和编译器之后,我们开始进行配置。

配置 VSCode

VSCode 的开发配置是基于文件夹的,因此选择一个你喜欢的位置作为日后 C/C++ 单文件开发的项目文件夹,然后在 VSCode 中打开这个文件夹(如果在安装 VSCode 的时候注册了右键菜单,可以右击然后选择“通过 Code 打开”)。最新的 VSCode 会提示安全问题,选择“是,我信任此作者”。

然后我们新建一个 C 或者 C++ 源代码文件,并编写任意一段合法代码。习惯起见,下面我一律以 C++ 为例。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    cout << "Hello World!" << endl;
    
    return 0;
}

编写完成之后,保存它。这个时候 VSCode 应该会提示你安装 C/C++ 语言开发插件,我们按照提示完成插件的安装。

插件安装完成之后,VSCode 会需要进行设置以配置 IntelliSense。最新版本的 VSCode 已经提供了图形化的界面,相比以前手动编写 JSON 会方便很多。点击“配置(UI)”。

在“编译器路径”一项中,正常情况下 VSCode 应该会检测到我们先前安装的 TDM-GCC,直接从下拉列表里选择即可。如果没有列出,那么就需要手动填写编译器安装目录下 bin 文件夹内编译器可执行文件的完整路径。关于选择 gcc 还是 g++,这里建议选择 g++。因为 G++ 编译 C 语言源代码文件比 GCC 编译 C++ 语言源代码文件会方便一些。

“编译器参数”部分,一般情况下我们需要的操作就是编译并输出可执行文件,因此填入下列内容即可,如后图所示。-std=c++17 可以不填,我这里只是比较喜欢用新一点的标准罢了。

-g
-std=c++17
${file}
-o
${fileDirname}\\${fileBasenameNoExtension}.exe

“IntelliSense 模式”选择 windows-gcc-x64

“包含路径”填写下列内容。注意根据自己安装的编译器路径进行调整。

${workspaceFolder}/**
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/10.3.0/include/c++/x86_64-w64-mingw32
C:/TDM-GCC-64/x86_64-w64-mingw32/include
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/10.3.0/include
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/10.3.0/include/c++/backward

“C 标准”根据喜好选择 c11 或者 c17。“C++ 标准”根据选择喜好选择 c++11 或者 c++17,注意这里和上面的 -std=c++17 保持一致。GCC 10.3.0 对于 c++20 的支持似乎不太好,想选的话应该也行。

完成配置之后关掉设置选项卡,返回源代码。如果一切配置妥当,这时候应该所有红线都消失了,并且按下 Shift + Alt + F 能够正确格式化代码。

按下 F5,会弹出调试配置选择,这里我们选择“C++ (Windows)”。

然后会提示正在下载依赖,耐心等待。不过比较诡异的是下载的是 C# 的依赖,我也不知道为什么。

接下来生成调试配置文件,选择“默认配置”。

这个时候会打开 .launch.json 文件。将原有的 configuration 数组的内容删除,点击右下角的“添加配置...”,选择“C/C++:(gdb) 启动”。这个时候配置文件应该会变成下图所示的样子。

我们需要修改 programmiDebuggerPathmiDebuggerPath 需要根据先前安装的编译器路径进行调整,使之指向 GDB 的可执行文件。修改后的文件内容如下。

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "C:/TDM-GCC-64/bin/gdb.exe",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

保存文件。点击“终端”→“配置默认生成任务...”,选择“C/C++:g++exe 生成活动文件”。

插件会根据我们之前填写的配置自动生成 tasks.json 文件,如图。

这里 args 数组的值有点问题需要修改,修改后的整个文件内容如下。

{
	"version": "2.0.0",
	"tasks": [
		{
			"type": "cppbuild",
			"label": "C/C++: g++.exe 生成活动文件",
			"command": "C:/TDM-GCC-64/bin/g++.exe",
			"args": [
				"-fdiagnostics-color=always",
				"-g",
				"-std=c++17",
				"${file}",
				"-o",
				"${fileDirname}\\${fileBasenameNoExtension}.exe"
			],
			"options": {
				"cwd": "C:/TDM-GCC-64/bin"
			},
			"problemMatcher": [
				"$gcc"
			],
			"group": {
				"kind": "build",
				"isDefault": true
			},
			"detail": "编译器: C:/TDM-GCC-64/bin/g++.exe"
		}
	]
}

对于初学者,可以酌情增加 -Wall 参数以帮助快速发现代码中的潜在问题。修改完毕之后保存。再次打开 launch.json 文件。向 configurations 数组里刚才配置好的项目加入 "preLaunchTask": "C/C++: g++.exe 生成活动文件",如下所示。这里的值对应了 tasks.jsontasks 数组配置好的项目中 label 的值。

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "C:/TDM-GCC-64/bin/gdb.exe",
            "preLaunchTask": "C/C++: g++.exe 生成活动文件",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

保存文件。返回到前面创建的 C/C++ 源代码文件。按下 F5,这时候会开始编译生成可执行文件并启动调试。在“调试控制台”选项卡中可以执行 GDB 命令,在“终端”选项卡中可以对程序进行输入输出。本文的例子中可以看到输出的 Hello World! 字样。

至此 VSCode 的配置即告完成。

使用 VSCode 进行断点调试

VSCode 的调试某种程度上来说师出 VS,比 Dev C++ 高到不知道哪里去了。下面来简单讲解一下如何进行断点调试。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int a;
    cin >> a;
    for (int i = 0; i < 10; i++)
    {
        a++;
    }
    cout << a << endl;

    return 0;
}

鼠标放在行号上,在行号的左边会出现一个小红点,点击它就成功在这一行打上了断点。我们在第 11 行 a++ 下断点。

按下 F5。前面提到在“终端”选项卡中可以进行输入输出。这里我们输入 1 作为 a 的初值。

回车之后会发现程序暂停执行了,同时第 11 行被高亮标注起来,表明当前程序暂停到了第 11 行之前的位置。需要注意的是,高亮行的代码在断点的时候还尚未执行。因此这时候 a 的值仍旧是 1。

在左侧的“变量”窗格中,可以看到当前作用域内所有局部变量的值。如果有全局变量,也会在这里显示出来。Registers 中列出了所有寄存器的值。“监视”窗格中可以根据自己的需要,设定一些要关注的表达式的值。“调用堆栈”窗格中展示了当前断点处的调用堆栈,这个功能在分析多个函数嵌套调用时很有帮助。“断点”窗格中显示了当前文件中所有的断点,点击前面的复选框可以临时禁用或启用一个断点,在这里也可以批量禁用或者启用所有断点,还可以直接删除所有的断点。

如果想删除已经打过的断点,可以再次点击行号前的小红点使它消失。

按下 F5 或者 F9 可以继续执行,如果在后面的执行中遇到断点,VSCode 会再次暂停,直到没有断点或程序退出。

Windows 下 VSCode 的单文件 C/C++ 配置大致就是这样。这一套足够应付所有涉及到 OJ 的单文件编程了。初学编程,还是要打好基础,养成好习惯。

评论

  1. FrankLee
    4月前
    2022-8-23 23:43:28

    怪,为啥只有大于号没有转义

  2. FrankLee
    已编辑
    4月前
    2022-8-23 23:38:15

    xmgg,断点调试的代码块处有误:< 被识别成了 < 。(闲的没事233,我不会说是我直接复制报错发现的(ó﹏ò。)ノ

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇