VScode 使用初步

什么是 VScode

Visual Studio Code(VScode) 是一个轻量级但功能强大的源代码编辑器,可在桌面上运行,并且可用于Windows,macOS和Linux。VS code 包括一整套系统:比如内部支持 JavaScript,TypeScript 和 Node.js,能够进行多种语言扩展(如 C++,C#,Java,Python,PHP,Go),也能够进行多种运行扩展(如.NET 和 Unity)。

简单的说就是 notepad+compiler+extensions。

VScode 特点

之前我也没有用过 VScode,一直用的都是 VS,Qt 这样的工具,但是真的用上 VScode 之后,就发现其实如果了解一下 VScode 的使用方式的话,这个工具使用起来还是比较简单的。主要的特点有:

  • 跨平台。VScode 能够运行在 macOS,Linux,Windows操作系统上
  • 轻便灵活。VScode 在最初安装只包含了开发流程共享的基本组件,只实现了包括编辑器,文件管理,窗口管理,首选项设置, JavaScript/TypeScript 语言服务和 Node.js 调试器等基本功能,此时的 VScode 就是一个代码编辑器
  • 可扩展。VS Code 扩展可以添加对以下内容的支持:
    • 语言:C++,C#,Go,Java,Python
    • 工具:ESLint,JSHint,PowerShell
    • 调试器:Chrome,PHP XDebug。
    • 键盘映射:Vim,Sublime Text,IntelliJ,Emacs,Atom,Visual Studio,Eclipse

hello world

这一部分以实际例子来说明 VScode 的使用方法,运行平台为 Linux,编程语言为 C/C++。

前提条件

  • GCC
  • GDB
  • VScode

建立工程

VScode 不同于 VS,Qt 可以直接新建工程,在 VScode 中需要自己手动建立工程目录。其实就是新建一个文件夹,也不需要在文件夹中包含类似 CMakeLists.txt 的文件,因为这样的文件会在之后自动生成。

然后打开 VScode,利用菜单栏中的 File 打开刚刚新建的新文件夹,该文件夹就是工程目录。

代码编辑

此时先写一个简单的 hello world 程序:

// main.cpp
#include <iostream>

using namespace std;

int main()
{
    cout<<"Hello world!"<<endl;

    return 0;
}

.vscode

默认情况下,在工程目录中会自动生成隐藏目录 .vscode,该文件中主要包含三个文件:

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

如果如果你此时没有看到该隐藏文件夹也没有关系,之后你构建上述三个文件中的任何一个文件都会生成该隐藏文件夹。

从这里来看,该隐藏文件夹有点像是 Qt 中的 .pro 文件。

task.json

既然代码已经写完了,接下来就是 build task 了。

在主菜单中,选择 Terminal > Configure Default Build Task。出现一个下拉列表,显示用于C++编译器的各种预定义构建任务。选择C/C++: g++ build active file。

这将在 .vscode 文件夹中创建 tasks.json 文件,并在编辑器中将其打开。tasks.json 文件应类似于以下 JSON:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558 
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

此时可以看到隐藏文件目录 .vscode 自动被创建。上边的参数有:

  • Command: 指定要运行的程序,在这种情况下是 g++
  • Args: 指定将传递给 g++ 的命令行参数。参数必须按照编译器期望的顺序指定
  • Label: 就是在任务列表中看到的值,可以随意命名
  • Group: "isDefault": true指定当按Ctrl+Shift+B时将运行此任务。此属性仅仅是为了便利性,如果将其设置为false,仍然可以通过terminal菜单中的Tasks: Run Build Task运行

此任务告诉 g++ 获取活动文件(${file}),对其进行编译,然后在当前目录(${fileDirname})中创建一个与活动文件同名但没有扩展名(${fileBasenameNoExtension)})的可执行文件,示例为 main。

运行程序

  1. 返回 main.cpp,任务将构建活动文件。
  2. 要运行 tasks.json 中定义的构建任务,按 Ctrl+Shift+B 或从 terminal 菜单中选择 Run Build Task。
  3. 任务启动时,会看到集成终端面板出现在源代码编辑器下方。任务完成后,终端将显示编译器的输出,指示构建成功还是失败。
  4. 使用 + 按钮创建一个新终端,这将在 WSL 上下文中运行一个 bash 终端,并以当前文件夹作为工作目录。
  5. 此时可以在终端运行 main。

launch.json

此时只是构建了任务,生成了可执行程序,但是想要调试的话还需要用到 launch.json 来设置调试器的相关内容。

  • 在菜单栏中选择 Run > Add Configuration...,然后选择 C++ (GDB/LLDB)
  • 然后将出现各种预定义调试配置的下拉列表。选择 g++ build and debug active file
  • VS Code 创建 launch.json 文件,在编辑器中打开为:
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - Build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

 上边的参数中:

  • Program: 指定要调试的程序。这里被设置为活动文件文件夹${fileDirname}和没有扩展名的活动文件名${fileBasenameNoExtension},如果helloworld.cpp是活动文件,则为helloworld
  • 默认情况下,C++扩展不会在源代码中添加任何断点,因此stopAtEntry值设置为false。stopAtEntry值为true时,调试器启动调试时遇到main方法停止

调试代码

  • 返回 main.cpp,使其成为活动文件
  • 按 F5 或从主菜单中选择 Run > Start Debugging。此时用户界面会发生一些更改:
    • 集成终端出现在源代码编辑器的底部。在 Debug Output 选项卡中,可以看到指示调试器已启动并正在运行
    • 编辑器突出显示main方法中的第一条语句。这是 C++ 扩展自动设置的断点
    • 左侧的 run 视图显示调试信息
    • 在代码编辑器的顶部,将显示一个调试控制面板

调试控制面板的使用方法与其它 IDE 基本相同。

WATCH

在调试的时候,左侧边栏会出现一个 WATCH 的栏目,利用 WATCH 可以实现对变量跟踪:

  • 在 WATCH 窗口中,单击加号,然后在文本框中键入 var(变量名),此时可以逐步调试程序,可以看出该变量一直显示在 WATCH
  • 在断点开启时,要快速查看任何变量的值,可以使用鼠标指针悬停在其上

c_cpp_properties.json

编程中通常会使用到一些第三方库,如果要用到第三方库的头文件的话,就需要在该文件中添加头文件目录,不过此时添加的头文件目录只是为了编程更加方法,实现智能感知,而并没有真正的链接。

真正的链接需要在 task.json 文件中设置参数,才能够正常编译。

可以通过从 Command Palette (Ctrl+Shift+P) 运行命令 C/C++: Edit Configurations (UI) 来查看 C/C++ 配置 UI。

  • 当在此处进行更改时,VS Code会将更改写入.vscode文件夹中的c_cpp_properties.json文件中。
  • 仅当程序包含不在工作空间或标准库路径中的头文件时,才需要修改includepath设置。

外部库链接的实例

当需要进行外部库链接时,至少需要在 tasks.json 中进行头文件包含和外部库链接,如果需要使用代码提示等智能感知功能的话,还需要修改 c_cpp_properties.json 文件。

以下用一个 C 语言的实例来简单说明需要进行外部库链接的情况(这里的静态库是利用这篇文章中的文件生成的):

// main.c
#include <stdio.h>
#include <node.h>

int main()
{
    printf("insert a node from tail\n");
    ND *head = createListTail();

//    printf("insert a node from head\n");
//    ND *head = createListHead();

    printf("traval all node using next\n");
    travalListNext(head);

    printf("insert a node\n");
    insertList(head,10);
    travalListNext(head);

//    printf("traval all node using pre\n");
//    travalListPre(head);

    printf("calculate the length of list\n");
    int length = lenList(head);
    printf("The length of list is %d\n",length);

    printf("search a node in list from single direction\n");
    ND *pp = searchNodeSdir(head,10);
    printf("The search node is %d\n",pp->data);

//    printf("search a node in list from both direction\n");
//    pp = searchNodeBdir(head,10);
//    printf("The search node is %d\n",pp->data);

    printf("delete a node\n");
    deleteNode(pp);
    travalListNext(head);

    printf("sort list by swap data\n");
    sortSwapData(head,9);
    travalListNext(head);

//    printf("sort list by swap pointer\n");
//    sortSwapPointer(head,9);
//    travalListNext(head);

    printf("destroy list\n");
    destroyList(head);
}
// tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "gcc build active file",
            "command": "/usr/bin/gcc",
            "args": [
                "-g",
                "${file}",
                "-I",
                "~/libr",
                "-L",
                "~/libr",
                "-l",
                "node",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
// launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gcc - Build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "gcc build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}
// c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "~/libr/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 4
}
  • 该工程需要的编译器是 gcc,而不是 g++
  • 如果在 c_cpp_properties.json 文件中没有为 includePath 参数添加头文件,则在 main.c 文件中的 #include <node.h> 会出现下划线,也就是说编辑器找不到该函数,但是实际是能够编译的。
  • 在 tasks.json 文件中添加了一些参数,如 -I,-L,-l 等,这些参数包含了头文件和外部链接库。
  • 不需要调试的话,可以不用添加 launch.json 文件

一个常见错误

当开始构建或调试时,xxx.cpp 不是活动文件时,最常见的错误原因(如 undefined _main 或 attempting to link with file built for unknown-unsupported file format 等)。这是因为编译器正在尝试编译不是源代码的内容(如 launch.json,tasks.json 或 c_cpp_properties.json 文件)。

因此,运行任务时一定要保证当前活动文件为包含 main 函数的文件。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值