VS code 配置 C、C++ 编译环境
VS code 配置 C、C++ 编译环境
因为vscode只是一个代码编辑器,没有自带有C/C++的编译器,因此我们需要安装一个C/C++编译器并且设置环境变量,推荐mingw
系列(指的是mingw或者mingw-w64,相比于mingw
,mingw-w64
更加强大),因为mingw也是后面提到的Code Runner插件默认的编译器,调试也是用的mingw。因为网络问题mingw-w64很难下载,推荐离线下载然后手动添加环境变量。
一、windows下安装mingw-w64
mingw-w64应该可以算是mingw的改进版本,mingw系列编译器是非常好的并且主流的c/c++编译器。
为了方便,一般我们会把gcc所在的路径加入系统的环境变量,这样就可以直接使用gcc命令而不用绝对路径。
右键计算机->属性->高级系统设置->环境变量,我们双击path,把我们gcc的路径C:\MinGW64\bin
添加进去。
确定以后 就可以在任意目录下直接使用gcc命令了。可以在任意目录打开cmd窗口,输入gcc -v
查看环境变量是否设置成功。如果显示版本信息则表示安装成功,如果仍然提示不是内部或外部命令,说明环境变量设置失败。
这里注意,环境变量的修改不会立即在Windows中生效,需要重启windows。
二、安装必要的插件
打开vscode,点击左面竖排第五个按钮,搜索并安装上如下三个插件,安装完成后重启vscode。
- chinese(simplified)
- C/C++
- Code Runner
三、编译运行程序
编译运行程序将介绍两种方法
- 使用之前安装好的
Code Runner插件
一键编译运行程序 - 打开vscode的
集成终端
使用命令行编译和运行
点击:文件>新建文件,出现一个空白文档,我准备了一段测试用的代码,请复制粘贴到空白文档中。
#include <stdio.h>
int main(void)
{
char name[100];
printf("What is your name?\n");
scanf("%s", name);
printf("Hello,%s,nice to meet you!\n", name);
return 0;
}
然后按Ctrl+S并将文件后缀名改为.c
或.cpp
后保存到电脑上,然后点击右上角的三角形按钮(原本这个位置没有,是安装Code Runner插件后新增的一键编译运行程序的按钮),或者按Ctrl+Alt+N就能编译运行当前程序。但是此时无法输入数据,也无法结束程序,先关闭vscode再重新打开一下,也就是重启一下vscode。
然后依次打开:文件>首选项>设置>用户>拓展>Run Code Configuration
找到Run In Terminal
打上勾现在程序已经可以正常运行了,此时程序是运行在vscode的集成终端上,并不会额外弹出一个控制台黑窗口。
这就是使用Code Runner插件运行程序的方法,点击右上角的垃圾桶图标可以直接结束程序运行。
Code Runner执行的指令可以修改,可以将默认使用的gcc/g++
换成clang
等,确实有需要的请看:修改Code Runner指令
下面将描述通过命令行指令编译运行程序的过程,刚接触的初学者在有些地方不明白也没关系,但希望你也能认真的看一遍
上面介绍的是一种偷懒的方法,它存在局限,看一个例子:
假设说我们在代码中使用了 winsock2.h
这个头文件,我们用刚刚的Code Runner插件
的方式编译会无法通过:
#include <winsock2.h>
#include <stdio.h>
int main()
{
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("Compile successfully!");
return 0;
}
PS E:\CodingWorkplace\C++> cd "e:\CodingWorkplace\C++\" ; if ($?) { gcc test.cpp -o test } ; if ($?) { .\test }
造成问题是原因是:Code Runner是按照预先设定好的规则(默认为mingw也就是gcc/g++ xxx.cpp -o xxx
),自动在终端执行编译运行的指令,也就上面显示的:
{ g++ test.cpp -o test }
如果是使用了winsock2.h
,同时又是使用gcc/g++
编译,在编译时我们应该在编译指令中额外添加-lwsock32
指令,而Code Runner模板中并没有这条指令。
即完整的编译指令应该是:
g++ xxx.cpp -o xxx.exe -lwsock32
为了解决这个问题,我们必须使用原始而科学的方法,直接在集成终端上用命令行编译和运行,vscode拥有一个集成终端,在集成终端上编写指令就相当于在cmd
(win7默认)或者powershell
(win10默认)等系统终端上编写指令。
按 Ctrl+~ 打开集成终端,先用cd
命令切换到源文件所在的文件夹,再使用gcc/g++
编译为可执行程序,最后运行程序,如果暂时不是很懂命令行,可以稍微学一下或者直接跳过这里。
PS E:\CodingWorkplace\C++> cd E:\CodingWorkplace\C++
PS E:\CodingWorkplace\C++> g++ .\test.cpp -o demo.exe -lwsock32
PS E:\CodingWorkplace\C++> .\demo.exe
Compile successfully!
PS E:\CodingWorkplace\C++>
三、调试程序
当程序遇到匪夷所思的BUG时,我们可以单步调试来定位错误,vscode拥有非常人性化的调试功能,支持添加断点,添加监视,显示鼠标指向变量的值,调试控制台查询变量值,详细细节我录制了一个演示视频,为了便于演示,我编写了一个常规的快速排序,从小到大排序十个数,仅仅是为了便于演示调试功能,初学者不理解不要紧。
https://www.bilibili.com/video/av63356142
下面开始正式配置调试环境
首先在电脑上你习惯的位置新建一个文件夹,用于存放编写的代码,接下来配置好的调试环境,仅会对存放在这一个文件夹以及文件夹的子目录里程序生效!
务必注意,调试的文件名和文件路径中不能出现中文字符!!否则将无法启动调试!
这是由于调试用到的mingw中的gdb不支持中文路径!并非是vscode的原因。
新建好文件夹后,在vscode界面,点击:文件>打开文件夹,打开刚刚新建的文件夹;
再点击新建文件夹在打开的文件夹下新建一个 .vscode
文件夹(注意前面的"."号)
然后在.vscode文件夹下新建两个json文件分别叫做
- launch.json
- tasks.json
本来这些是可以自动生成的,但有的地方不方便阐述,因此直接手动新建。
然后将下面的代码复制到对应的json文件中去并保存
launch.json
launch.json中需要修改一处:"configurations"
中"miDebuggerPath"
选项需要设置为你的调试程序gdb.exe
所在位置的绝对路径,这里的是我电脑上mingw -w64的安装位置。
无论安装的是mingw还是mingw-w64,都会有一个gdb.exe
在安装目录的bin
文件夹下,一定要把对应的路径修正否则无法调试。
{
"version": "0.2.0",
"configurations": [
{
// 配置名称,将会在启动配置的下拉菜单中显示
"name": "C/C++",
// 配置类型,这里只能为cppdbg
"type": "cppdbg",
// 请求配置类型,可以为launch(启动)或attach(附加)
"request": "launch",
// 将要进行调试的程序的路径
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
// 程序调试时传递给程序的命令行参数,一般设为空即可
"args": [],
// 设为true时程序将暂停在程序入口处,一般设置为false
"stopAtEntry": false,
// 调试程序时的工作目录,一般为${workspaceRoot}即代码所在目录
"cwd": "${workspaceFolder}",
"environment": [],
// 调试时是否显示控制台窗口,一般设置为true显示控制台
"externalConsole": true,
"MIMode": "gdb",
// miDebugger的路径,注意这里要与MinGw的路径对应
"miDebuggerPath": "C:\\RunTimes\\MinGW-w64\\bin\\gdb.exe",
// 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc
"preLaunchTask": "g++",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
},
]
}
tasks.json
{
"version": "2.0.0",
"command": "g++",
// 编译命令参数
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}.exe"
],
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
"group": {
"kind": "build",
"isDefault": true
}
}
事实上现在已经可以正常调试了。
并且此时可以按 ctrl+shift+b 直接调用配置好的g++ task 编译程序而不运行程序,类似于一些IDE的编译选项。
测试一下,在CODE文件夹下新建一个.cpp
文件将我之前视频演示中的代码粘贴进去,并在适当的地方添加上断点。
#include <bits/stdc++.h>
using namespace std;
void quicksort(int A[], int l, int r)
{
int m = l;
for (int i = l; i < r; i++)
{
if (A[i] < A[r])
{
swap(A[i], A[m]);
++m;
}
}
swap(A[m], A[r]);
if (m > l + 1)
quicksort(A, l, m - 1);
if (m < r - 1)
quicksort(A, m + 1, r);
}
int main(void)
{
int A[10], n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> A[i];
}
quicksort(A, 0, n - 1);
for (int i = 0; i < n; i++)
{
cout << A[i] << endl;
}
return 0;
}
按f5
或者启动调试的按钮启动调试,程序执行到断点处会停下
六个按钮分别代表
- 继续执行到下一个断点处
- 执行下一条语句,遇到函数直接执行完不会跳转进函数
- 执行下一条语句,遇到函数会跳转进函数继续单步执行
- 跳出当前所在的函数,如果是主函数会结束程序
- 重新启动调试
- 结束调试
如果是希望像我视频演示中一样,启动调试后不再额外显示黑窗口而是像之前Code Runner插件那样在界面下方显示终端进行调试:
只需将launch.json
中的"externalConsole"
后面的值由true
改为false
。
在单步调试的过程中我们可以添加监视来实时监视变量或表达式值的变化:
也可以在调试控制台
中输入想获取结果的变量名或者表达式获得当前的值:
或者直接将鼠标光标移动到变量位置上,会自动显示当前变量的值:
如果数组开得过大或者是一些结构较复杂的类或结构体,查询或显示值可能会导致调试程序崩溃。
类似于code runner的问题: 如果是需要有额外的编译指令如-lwsock32
,需要调试前事先在tasks.json的args
处添加上对应的指令,或者用 // 注释掉 launch.json 中的 preLaunchTask:"g++"(启动调试前执行g++编译,按tasks指令格式编译)这一项,然后自己再按 ctrl + ~ 打开终端手动编译好后再执行调试。
记住:调试是属于工作区设置,当前配置的调试环境只会对当前.vscode文件夹所在路径下的文件生效,如果要换用别的文件夹,把 .vscode 这个文件夹拷贝过去即可。