在 VS Code 中试用

配置 VS Code 以使用 Microsoft C++

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

配置 VS Code 后,你将在 VS Code 中编译和调试一个简单的 Hello World 程序。本教程不讲解 Microsoft C++ 工具集或 C++ 语言的详细信息。有关这些主题,网上有许多优秀的资源可供参考。

如果遇到任何问题,请随时在 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 安装程序,并确认已选中 C++ 工作负载。如果尚未安装,则选中该复选框,然后在安装程序中选择修改按钮。

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

    Build Tools for Visual Studio download

    这将启动 Visual Studio 安装程序,该程序会显示一个对话框,其中包含可用的 Visual Studio Build Tools 工作负载。勾选使用 C++ 的桌面开发工作负载,然后选择安装

    Cpp build tools workload

注意:你可以使用 Visual Studio Build Tools 中的 C++ 工具集以及 Visual Studio Code 来开发、构建和测试任何 C++ 代码,前提是你拥有有效的 Visual Studio 许可证(Community、Pro 或 Enterprise 均可)。

检查 Microsoft Visual C++ 安装

要从命令行或 VS Code 使用 MSVC,必须从 Developer Command Prompt for Visual Studio 运行。普通的 shell,例如 PowerShell、Bash 或 Windows 命令提示符,没有设置必要的路径环境变量。

要打开适用于 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}) 中创建一个与活动文件同名但扩展名为 .exe 的可执行文件 (/Fe: 开关) (${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++ 配置界面。

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

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

{
  "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、函数、脚本文件或可执行程序的名称”,这通常意味着你在 Developer Command Prompt for Visual Studio 外部运行 VS Code,并且 VS Code 不知道 cl.exe 编译器的路径。

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

你可以通过打开新的终端 (⌃⇧` (Windows, Linux Ctrl+Shift+`)) 并键入“cl”来验证 cl.exe 是否可供 VS Code 使用,从而随时检查你是否正在 Developer Command Prompt 的上下文中运行 VS Code。

致命错误 C1034: assert.h: 未设置包含路径

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

下一步

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