在 VS Code 中尝试

配置 VS Code 以用于 Microsoft C++

在本教程中,你将配置 Visual Studio Code 以在 Windows 上使用 Microsoft Visual C++ 编译器和调试器。

配置 VS Code 后,你将在 VS Code 中编译和调试一个简单的 Hello World 程序。本教程不涉及 Microsoft C++ 工具集或 C++ 语言的详细信息。对于这些主题,Web 上有许多好的资源可用。

如果你遇到任何问题,请随时在 VS Code 文档存储库 中为本教程提交问题。

先决条件

要成功完成本教程,你必须执行以下操作

  1. 安装 Visual Studio Code

  2. 安装 适用于 VS Code 的 C/C++ 扩展。你可以在扩展视图 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 中搜索“c++”来安装 C/C++ 扩展。

    C/C++ extension

  3. 安装 Microsoft Visual C++ (MSVC) 编译器工具集。

    如果你已安装了最新版本的 Visual Studio,请从 Windows“开始”菜单中打开 Visual Studio Installer,并确认已勾选 C++ 工作负载。如果未安装,则勾选该框并在安装程序中选择 修改 按钮。

    你也可以在不安装完整 Visual Studio IDE 的情况下安装 使用 C++ 的桌面开发 工作负载。在 Visual Studio 下载 页面,向下滚动到 所有下载 部分,找到 Visual Studio 的工具,然后选择 Build Tools for Visual Studio 2022 的下载。

    Build Tools for Visual Studio download

    这将启动 Visual Studio Installer,它会弹出一个对话框,显示可用的 Visual Studio Build Tools 工作负载。勾选 使用 C++ 的桌面开发 工作负载,然后选择 安装

    Cpp build tools workload

注意:你可以将 Visual Studio Build Tools 中的 C++ 工具集与 Visual Studio Code 一起使用,以编译、构建和验证任何 C++ 代码库,前提是你也拥有有效的 Visual Studio 许可证(无论是 Community、Pro 还是 Enterprise),并且正在积极地使用该许可证开发该 C++ 代码库。

检查 Microsoft Visual C++ 安装

要从命令行或 VS Code 使用 MSVC,必须从 适用于 Visual Studio 的 Developer Command Prompt 运行。普通的 Shell(例如 PowerShell、Bash 或 Windows 命令提示符)未设置必要的 PATH 环境变量。

要打开 VS 的 Developer Command Prompt,请在 Windows“开始”菜单中输入“developer”,你应该会在建议列表中看到它出现。确切的名称取决于你安装的 Visual Studio 版本或 Visual Studio Build Tools 版本。选择该项以打开提示符。

Developer Command Prompt

你可以通过输入“cl”来测试是否正确安装了 C++ 编译器 cl.exe,你应该会看到带有版本和基本使用说明的版权信息。

Checking cl.exe installation

如果 Developer Command Prompt 使用 BuildTools 位置作为起始目录(你不应该将项目放在那里),请在开始创建新项目之前导航到你的用户文件夹 (C:\users\{你的用户名}\)。

注意:如果由于某种原因你无法从 Developer Command Prompt 运行 VS Code,你可以在 在 Developer Command Prompt 之外运行 VS Code 中找到在 VS Code 中构建 C++ 项目的替代方法。

创建 Hello World

在 Developer Command Prompt 中,创建一个名为 "projects" 的空文件夹,用于存储所有 VS Code 项目,然后创建一个名为 "helloworld" 的子文件夹,导航到该文件夹,然后输入以下命令在该文件夹 (.) 中打开 VS Code (code)

mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .

命令 "code ." 在当前工作文件夹中打开 VS Code,该文件夹成为你的“工作区”。完成本教程后,你会在工作区中的 .vscode 文件夹中看到创建了三个文件

  • tasks.json(构建指令)
  • launch.json(调试器设置)
  • c_cpp_properties.json(编译器路径和 IntelliSense 设置)

添加源代码文件

在文件资源管理器标题栏中,选择 新建文件 按钮,并将文件命名为 helloworld.cpp

New File title bar button

添加 hello world 源代码

现在粘贴以下源代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};

    for (const string& word : msg)
    {
        cout << word << " ";
    }
    cout << endl;
}

现在按 ⌘S (Windows、Linux Ctrl+S) 保存文件。请注意,刚刚添加的文件如何出现在 VS Code 侧边栏中的 文件资源管理器 视图 (⇧⌘E (Windows、Linux Ctrl+Shift+E)) 中

File Explorer

你也可以通过在主菜单的 文件 中勾选 自动保存 来启用 自动保存,以自动保存文件更改。

最左侧的活动栏允许你打开不同的视图,例如 搜索源代码管理运行。你将在本教程稍后查看运行视图。你可以在 VS Code 用户界面文档中找到有关其他视图的更多信息。

注意:当你保存或打开 C++ 文件时,你可能会看到 C/C++ 扩展的通知,提示有 Insiders 版本可用,该版本允许你测试新功能和修复。你可以通过选择 X清除通知)来忽略此通知。

探索 IntelliSense

在新的 helloworld.cpp 文件中,将鼠标悬停在 vectorstring 上以查看类型信息。在声明 msg 变量后,开始输入 msg.,就像调用成员函数一样。你应该会立即看到一个完成列表,其中显示所有成员函数,以及一个显示 msg 对象的类型信息的窗口

Statement completion IntelliSense

你可以按 Tab 键插入选定的成员;然后,当你添加左括号时,你将看到有关函数所需的任何参数的信息。

运行 helloworld.cpp

请记住,C++ 扩展使用你计算机上安装的 C++ 编译器来构建程序。在尝试在 VS Code 中运行和调试 helloworld.cpp 之前,请确保已安装 C++ 编译器。

  1. 打开 helloworld.cpp,使其成为活动文件。

  2. 单击编辑器右上角的播放按钮。

    Screenshot of helloworld.cpp and play button

  3. 从系统中检测到的编译器列表中选择 C/C++: cl.exe 生成并调试活动文件

    C++ debug configuration dropdown

你只会在第一次运行 helloworld.cpp 时被要求选择编译器。该编译器将作为 tasks.json 文件中的“默认”编译器设置。

  1. 构建成功后,你的程序输出将出现在集成的 终端 中。

    screenshot of program output

如果在使用 cl.exe 构建和调试时出错,请确保你已使用 code . 快捷方式从 适用于 Visual Studio 的 Developer Command Prompt 启动了 VS Code。

Error notification when trying to use MSVC without running VS Code from the Developer Command Prompt for VS

第一次运行程序时,C++ 扩展会创建 tasks.json,你会在项目的 .vscode 文件夹中找到它。tasks.json 存储构建配置。

新创建的 tasks.json 文件应类似于下面的 JSON

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "problemMatcher": ["$msCompile"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ]
}

注意:你可以在 变量参考 中了解有关 tasks.json 变量的更多信息。

command 设置指定要运行的程序;在本例中为 "cl.exe"。args 数组指定将传递给 cl.exe 的命令行参数。这些参数必须按照编译器期望的顺序指定。

此任务告知 C++ 编译器获取活动文件 (${file}),对其进行编译,并在当前目录 (${fileDirname}) 中创建一个可执行文件 (/Fe: 开关),其名称与活动文件相同,但扩展名为 .exe (${fileBasenameNoExtension}.exe),例如我们的示例将生成 helloworld.exe

label 值是你在任务列表中看到的名称;你可以将其命名为任何你喜欢的名称。

detail 值是你在任务列表中看到的任务描述。强烈建议更改此名称以将其与类似任务区分开来。

problemMatcher 值选择用于在编译器输出中查找错误和警告的输出解析器。对于 cl.exe,如果使用 $msCompile 问题匹配器,将获得最佳结果。

从现在开始,播放按钮将读取 tasks.json 以确定如何构建和运行你的程序。你可以在 tasks.json 中定义多个构建任务,并且标记为默认的任务将由播放按钮使用。如果需要更改默认编译器,可以运行 任务: 配置默认生成任务。或者,你可以修改 tasks.json 文件,并通过替换以下段落来删除默认设置

    "group": {
        "kind": "build",
        "isDefault": true
    },

替换为以下内容

    "group": "build",

修改 tasks.json

你可以通过使用 "${workspaceFolder}/*.cpp" 这样的参数而不是 "${file}" 来修改 tasks.json 以构建多个 C++ 文件。这将构建当前文件夹中的所有 .cpp 文件。你还可以通过将 "${fileDirname}\\${fileBasenameNoExtension}.exe" 替换为硬编码文件名(例如 "${workspaceFolder}\\myProgram.exe")来修改输出文件名。

调试 helloworld.cpp

要调试你的代码,

  1. 回到 helloworld.cpp,使其成为活动文件。
  2. 通过单击编辑器边距或在当前行按 F9 设置断点。helloworld.cpp 中的断点截图
  3. 从播放按钮旁边的下拉菜单中,选择 调试 C/C++ 文件播放按钮下拉菜单截图
  4. 从系统中检测到的编译器列表中选择 C/C++: cl.exe 生成并调试活动文件(你只会在第一次运行或调试 helloworld.cpp 时被要求选择编译器)。C++ 调试配置下拉菜单

播放按钮有两种模式:运行 C/C++ 文件调试 C/C++ 文件。它将默认使用上次使用的模式。如果你在播放按钮中看到调试图标,则可以直接选择播放按钮进行调试,而无需选择下拉菜单项。

如果在使用 cl.exe 构建和调试时出错,请确保你已使用 code . 快捷方式从 适用于 Visual Studio 的 Developer Command Prompt 启动了 VS Code。

Error notification when trying to use MSVC without running VS Code from the Developer Command Prompt for VS

探索调试器

在开始单步调试代码之前,让我们花点时间注意用户界面中的一些变化

  • 集成终端出现在源代码编辑器的底部。在调试输出选项卡中,你将看到表明调试器已启动并正在运行的输出。

  • 编辑器会突出显示你在启动调试器之前设置断点的那一行

    Initial breakpoint

  • 左侧的运行和调试视图显示调试信息。你将在本教程稍后看到一个示例。

  • 在代码编辑器的顶部,会出现一个调试控制面板。你可以通过抓住左侧的点将其在屏幕上移动。

    Debugging controls

单步调试代码

现在你已准备好开始单步调试代码。

  1. 单击或按下调试控制面板中的跳过图标。

    Step over button

    这将使程序执行前进到 for 循环的第一行,并跳过创建和初始化 msg 变量时在 vectorstring 类中调用的所有内部函数调用。注意左侧变量窗口中的变化。

    Debugging windows

    在这种情况下,错误是预期的,因为尽管循环的变量名现在对调试器可见,但该语句尚未执行,因此此时没有什么可读取的。然而,msg 的内容是可见的,因为该语句已完成。

  2. 再次按下跳过以进入程序中的下一条语句(跳过用于初始化循环的所有内部代码)。现在,变量窗口显示了有关循环变量的信息。

  3. 再次按下跳过以执行 cout 语句。(请注意,C++ 扩展在循环退出之前不会向调试控制台输出任何内容。)

  4. 如果你愿意,可以继续按下跳过直到 vector 中的所有单词都打印到控制台。但是如果你好奇,可以尝试按下单步进入按钮来单步调试 C++ 标准库中的源代码!

    Breakpoint in gcc standard library header

    要返回到你自己的代码,一种方法是继续按下跳过。另一种方法是在代码编辑器中切换到 helloworld.cpp 选项卡,将插入点放在循环内部的 cout 语句上,然后按下 F9 来设置断点。左侧的边距中会出现一个红点,表示在此行设置了断点。

    Breakpoint in main

    然后按下 F5 从标准库头文件中的当前行开始执行。执行将在 cout 处中断。如果你愿意,可以再次按下 F9 来关闭断点。

设置监视

有时你可能希望在程序执行时跟踪变量的值。你可以通过在变量上设置监视来实现。

  1. 将插入点放在循环内部。在监视窗口中,选择加号,然后在文本框中输入 word,这是循环变量的名称。现在在你单步调试循环时查看监视窗口。

    Watch window

  2. 在循环之前添加此语句:int i = 0; 来添加另一个监视。然后,在循环内部添加此语句:++i;。现在像上一步一样为 i 添加监视。

  3. 要在执行暂停在断点处时快速查看任何变量的值,可以将鼠标指针悬停在其上。

    Mouse hover

使用 launch.json 自定义调试

当你使用播放按钮或 F5 进行调试时,C++ 扩展会动态创建调试配置。

在某些情况下,你可能需要自定义调试配置,例如指定在运行时传递给程序的参数。你可以在 launch.json 文件中定义自定义调试配置。

要创建 launch.json,请从播放按钮下拉菜单中选择 添加调试配置

Add debug configuration play button menu

然后你将看到一个包含各种预定义调试配置的下拉菜单。选择 C/C++: cl.exe 生成并调试活动文件

C++ debug configuration dropdown

VS Code 创建一个 launch.json 文件,它看起来像这样

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: cl.exe build and debug active file",
      "type": "cppvsdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "preLaunchTask": "C/C++: cl.exe build active file"
    }
  ]
}

在上面的 JSON 中,program 指定要调试的程序。此处将其设置为活动文件所在的文件夹 (${fileDirname}) 和带有 .exe 扩展名的活动文件名 (${fileBasenameNoExtension}.exe),如果活动文件是 helloworld.cpp,则将是 helloworld.exeargs 属性是在运行时传递给程序的参数数组。

默认情况下,C++ 扩展不会在你的源代码中添加任何断点,并且 stopAtEntry 的值设置为 false

stopAtEntry 值更改为 true,以使调试器在启动调试时停在 main 方法处。

从现在开始,播放按钮和 F5 在启动程序进行调试时将读取你的 launch.json 文件。

C/C++ 配置

如果你想对 C/C++ 扩展有更多控制,可以创建一个 c_cpp_properties.json 文件,该文件允许你更改编译器路径、包含路径、C++ 标准(默认为 C++17)等设置。

你可以通过从命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 运行命令 C/C++: 编辑配置 (UI) 来查看 C/C++ 配置 UI。

Command Palette

这会打开 C/C++ 配置页面。当你在此处进行更改时,VS Code 会将它们写入 .vscode 文件夹中名为 c_cpp_properties.json 的文件。

Command Palette

Visual Studio Code 将这些设置放在 .vscode\c_cpp_properties.json 中。如果直接打开该文件,它应该看起来像这样

{
  "configurations": [
    {
      "name": "Win32",
      "includePath": ["${workspaceFolder}/**"],
      "defines": ["_DEBUG", "UNICODE", "_UNICODE"],
      "windowsSdkVersion": "10.0.18362.0",
      "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "msvc-x64"
    }
  ],
  "version": 4
}

仅当你的程序包含不在工作区或标准库路径中的头文件时,才需要将路径添加到 包含路径 数组设置中。

编译器路径

compilerPath 设置是配置中的一个重要设置。扩展使用它来推断 C++ 标准库头文件的路径。当扩展知道在哪里可以找到这些文件时,它可以提供智能完成和转到定义导航等有用功能。

C/C++ 扩展会尝试根据在你的系统上找到的信息填充 compilerPath 的默认编译器位置。扩展会在几个常见的编译器位置查找。

compilerPath 搜索顺序为

  • 首先检查 Microsoft Visual C++ 编译器
  • 然后在适用于 Linux 的 Windows 子系统 (WSL) 上查找 g++
  • 然后是 Mingw-w64 的 g++。

如果你安装了 g++ 或 WSL,你可能需要更改 compilerPath 以匹配项目首选的编译器。对于 Microsoft C++,路径应该类似于这样,具体取决于你安装的特定版本:"C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe"。

重复使用 C++ 配置

VS Code 现在已配置为使用 Microsoft C++ 编译器。此配置适用于当前工作区。要重复使用配置,只需将 JSON 文件复制到新项目文件夹(工作区)的 .vscode 文件夹中,并根据需要更改源文件和可执行文件的名称。

在 Developer Command Prompt 之外运行 VS Code

在某些情况下,无法从 适用于 Visual Studio 的 Developer Command Prompt 运行 VS Code(例如,在通过 SSH 进行远程开发的场景中)。在这种情况下,你可以使用以下 tasks.json 配置在构建期间自动化初始化 适用于 Visual Studio 的 Developer Command Prompt

{
  "version": "2.0.0",
  "windows": {
    "options": {
      "shell": {
        "executable": "cmd.exe",
        "args": [
          "/C",
          // The path to VsDevCmd.bat depends on the version of Visual Studio you have installed.
          "\"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/Common7/Tools/VsDevCmd.bat\"",
          "&&"
        ]
      }
    }
  },
  "tasks": [
    {
      "type": "shell",
      "label": "cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "problemMatcher": ["$msCompile"],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

注意VsDevCmd.bat 的路径可能因 Visual Studio 版本或安装路径而异。你可以通过打开命令提示符并运行 dir "\VsDevCmd*" /s 来查找 VsDevCmd.bat 的路径。

疑难解答

术语“cl.exe”无法识别

如果看到错误“术语‘cl.exe’无法识别为 cmdlet、函数、脚本文件或可运行程序的名称”,这通常意味着你正在 适用于 Visual Studio 的 Developer Command Prompt 之外运行 VS Code,并且 VS Code 不知道 cl.exe 编译器的路径。

VS Code 必须从适用于 Visual Studio 的 Developer Command Prompt 启动,或者必须将任务配置为 在 Developer Command Prompt 之外运行

你总是可以通过打开一个新终端 (⌃⇧` (Windows、Linux Ctrl+Shift+`)) 并输入“cl”来检查你是否在 Developer Command Prompt 的上下文中运行 VS Code,以验证 cl.exe 对 VS Code 可用。

fatal error C1034: assert.h: 未设置包含路径

在这种情况下,通过 PATH 环境变量,VS Code 可以使用 cl.exe,但 VS Code 仍然需要从 适用于 Visual Studio 的 Developer Command Prompt 启动,或者配置为 在 Developer Command Prompt 之外运行。否则,cl.exe 无法访问重要的环境变量,例如 INCLUDE

下一步

  • 浏览 VS Code 用户指南
  • 查看 C++ 扩展概述
  • 创建一个新的工作区,将你的 .vscode JSON 文件复制到其中,根据新的工作区路径、程序名称等调整必要的设置,然后开始编码!