🚀 在 VS Code 中免費取得

在 VS Code 中於 Linux 上使用 C++

在本教學課程中,您將設定 Visual Studio Code 以在 Linux 上使用 GCC C++ 編譯器 (g++) 和 GDB 除錯工具。GCC 代表 GNU Compiler Collection;GDB 則是 GNU 除錯工具。

設定 VS Code 後,您將在 VS Code 中編譯和除錯一個簡單的 C++ 程式。本教學課程不會教您 GCC、GDB、Ubuntu 或 C++ 語言。關於這些主題,網路上有許多優良資源可供參考。

如果您遇到問題,歡迎在本教學課程的 VS Code 文件儲存庫中提交問題。

先決條件

若要成功完成本教學課程,您必須執行下列步驟

  1. 安裝 Visual Studio Code

  2. 安裝 VS Code 的 C++ 擴充功能。您可以透過在「擴充功能」檢視中搜尋 'c++' 來安裝 C/C++ 擴充功能 (⇧⌘X (Windows、Linux Ctrl+Shift+X))。

    C/C++ extension

確保已安裝 GCC

雖然您將使用 VS Code 來編輯原始程式碼,但您將在 Linux 上使用 g++ 編譯器來編譯原始程式碼。您也將使用 GDB 進行除錯。這些工具預設未安裝在 Ubuntu 上,因此您必須安裝它們。幸運的是,這很容易。

首先,檢查是否已安裝 GCC。若要驗證是否已安裝,請開啟「終端機」視窗並輸入下列命令

gcc -v

如果未安裝 GCC,請從終端機視窗執行下列命令,以更新 Ubuntu 套件清單。過時的 Linux 發行版有時會干擾安裝新套件的嘗試。

sudo apt-get update

接下來,使用下列命令安裝 GNU 編譯器工具和 GDB 除錯工具

sudo apt-get install build-essential gdb

建立 Hello World

從終端機視窗中,建立一個名為 projects 的空資料夾來儲存您的 VS Code 專案。然後建立一個名為 helloworld 的子資料夾,導覽至該資料夾,並輸入下列命令以在該資料夾中開啟 VS Code

mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .

code . 命令會在目前的工作資料夾中開啟 VS Code,而該資料夾會成為您的「工作區」。在您完成本教學課程的過程中,您將在工作區的 .vscode 資料夾中建立三個檔案

  • tasks.json (編譯器建置設定)
  • launch.json (除錯工具設定)
  • c_cpp_properties.json (編譯器路徑和 IntelliSense 設定)

新增 Hello World 原始程式碼檔案

在「檔案總管」標題列中,選取 [新增檔案] 並將檔案命名為 helloworld.cpp

New File title bar button

貼上下列原始程式碼

#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;

    return 0;
}

現在按下 ⌘S (Windows、Linux Ctrl+S) 以儲存檔案。請注意,您的檔案會列在 VS Code 側邊欄的「檔案總管」檢視中 (⇧⌘E (Windows、Linux Ctrl+Shift+E))

File Explorer

您也可以透過在主「檔案」選單中勾選 [自動儲存] 來啟用「自動儲存」,以自動儲存您的檔案變更。

Visual Studio Code 邊緣的「活動列」可讓您開啟不同的檢視,例如 [搜尋]、[原始檔控制] 和 [執行]。您將在本教學課程稍後查看 [執行] 檢視。您可以在 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. 從系統上偵測到的編譯器清單中,選擇 [g++ 建置並除錯作用中檔案]。

    C++ debug configuration dropdown

您只會在第一次執行 helloworld.cpp 時被要求選擇編譯器。此編譯器將在 tasks.json 檔案中設定為「預設」編譯器。

  1. 建置成功後,您的程式輸出將會出現在整合式「終端機」中。

    screenshot of program output

第一次執行程式時,C++ 擴充功能會建立 tasks.json,您會在專案的 .vscode 資料夾中找到它。tasks.json 儲存建置組態。

您新的 tasks.json 檔案應該看起來類似於下方的 JSON

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: 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
      },
      "detail": "Task generated by Debugger."
    }
  ]
}

注意:您可以在變數參考中深入了解 tasks.json 變數

command 設定指定要執行的程式;在本例中為 g++。args 陣列指定將傳遞至 g++ 的命令列引數。這些引數必須以編譯器預期的順序指定。

此工作會指示 g++ 採用作用中檔案 (${file})、編譯它,並在目前目錄 (${fileDirname}) 中建立一個可執行檔,該檔案的名稱與作用中檔案相同,但不含副檔名 (${fileBasenameNoExtension}),在本例中會產生 helloworld

label 值是您在工作清單中看到的內容;您可以將其命名為任何您喜歡的名稱。

detail 值是您在工作清單中看到的任務描述。強烈建議您重新命名此值,以將其與類似任務區分開來。

從現在開始,播放按鈕將從 tasks.json 讀取,以判斷如何建置和執行您的程式。您可以在 tasks.json 中定義多個建置工作,而標記為預設的工作將由播放按鈕使用。如果您需要變更預設編譯器,您可以執行 [工作: 設定預設建置工作]。或者,您可以修改 tasks.json 檔案,並透過取代此區段來移除預設值

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

為此

    "group": "build",

修改 tasks.json

您可以修改 tasks.json 以建置多個 C++ 檔案,方法是使用類似 "${workspaceFolder}/*.cpp" 而不是 "${file}" 的引數。這將建置目前資料夾中的所有 .cpp 檔案。您也可以透過將 "${fileDirname}/${fileBasenameNoExtension}" 替換為硬式編碼的檔案名稱 (例如 'helloworld.out') 來修改輸出檔案名稱。

除錯 helloworld.cpp

若要除錯您的程式碼,

  1. 返回 helloworld.cpp,使其成為作用中檔案。
  2. 透過按一下編輯器邊界或在目前行上使用 F9 來設定中斷點。 helloworld.cpp 中斷點的螢幕擷取畫面
  3. 從播放按鈕旁的下拉式選單中,選取 [除錯 C/C++ 檔案]。 播放按鈕下拉式選單的螢幕擷取畫面
  4. 從系統上偵測到的編譯器清單中,選擇 [C/C++: g++ 建置並除錯作用中檔案] (您只會在第一次執行或除錯 helloworld.cpp 時被要求選擇編譯器)。 C++ 除錯組態下拉式選單

播放按鈕有兩種模式:[執行 C/C++ 檔案] 和 [除錯 C/C++ 檔案]。它會預設為上次使用的模式。如果您在播放按鈕中看到除錯圖示,您可以直接選取播放按鈕進行除錯,而無需選取下拉式選單項目。

探索除錯工具

在您開始逐步執行程式碼之前,我們先花一點時間注意使用者介面中的幾個變更

  • 「整合式終端機」會出現在原始程式碼編輯器的底部。在 [除錯輸出] 索引標籤中,您會看到輸出,指出除錯工具已啟動並執行。

  • 編輯器會醒目提示第 12 行,這是您在啟動除錯工具之前設定的中斷點

    Initial breakpoint

  • 左側的 [執行與除錯] 檢視會顯示除錯資訊。您將在本教學課程稍後看到一個範例。

  • 在程式碼編輯器的頂端,會出現一個除錯控制面板。您可以抓住左側的點,在螢幕上移動它。

    Debugging controls

如果您的工作區中已有 launch.json 檔案,則播放按鈕會在判斷如何執行和除錯 C++ 檔案時從中讀取。如果您沒有 launch.json,則播放按鈕會動態建立暫時的「快速除錯」組態,完全無需 launch.json!

逐步執行程式碼

現在您已準備好開始逐步執行程式碼。

  1. 按一下或按下除錯控制面板中的 [逐步跳過] 圖示。

    Step over button

    這會將程式執行推進到 for 迴圈的第一行,並跳過在建立和初始化 msg 變數時在 vectorstring 類別中呼叫的所有內部函式呼叫。請注意側邊「變數」視窗中的變更。

    Debugging windows

  2. 再次按下 [逐步跳過] 以推進到此程式中的下一個陳述式 (跳過為初始化迴圈而執行的所有內部程式碼)。現在,「變數」視窗會顯示關於迴圈變數的資訊。

  3. 再次按下 [逐步跳過] 以執行 cout 陳述式。(請注意,C++ 擴充功能在最後一個 cout 執行之前,不會將任何輸出列印到「除錯主控台」。)

  4. 如果您願意,您可以持續按下 [逐步跳過],直到向量中的所有字詞都已列印到主控台。但如果您好奇,請嘗試按下 [逐步進入] 按鈕,以逐步執行 C++ 標準程式庫中的原始程式碼!

    Breakpoint in gcc standard library header

    若要返回您自己的程式碼,一種方法是持續按下 [逐步跳過]。另一種方法是在您的程式碼中設定中斷點,方法是切換到程式碼編輯器中的 helloworld.cpp 索引標籤,將插入點放在迴圈內 cout 陳述式的某個位置,然後按下 F9。左側的邊界中會出現一個紅點,表示已在此行設定中斷點。

    Breakpoint in main

    然後按下 F5 從標準程式庫標頭中的目前行開始執行。執行將在 cout 處中斷。如果您願意,您可以再次按下 F9 以切換關閉中斷點。

    當迴圈完成時,您可以在整合式終端機的 [除錯主控台] 索引標籤中看到輸出,以及 GDB 輸出的一些其他診斷資訊。

    Debug console display

設定監看式

若要在程式執行時追蹤變數的值,請在變數上設定監看式。

  1. 將插入點放在迴圈內。在 [監看式] 視窗中,按一下加號,並在文字方塊中輸入 word,這是迴圈變數的名稱。現在,在您逐步執行迴圈時,檢視 [監看式] 視窗。

    Watch window

  2. 若要在執行暫停在中斷點時快速檢視任何變數的值,您可以將滑鼠游標停留在其上方。

    Mouse hover

接下來,您將建立 tasks.json 檔案,以告知 VS Code 如何建置 (編譯) 程式。此工作將叫用 g++ 編譯器,以從原始程式碼建立可執行檔。

helloworld.cpp 在編輯器中保持開啟狀態非常重要,因為下一步會使用編輯器中的作用中檔案作為內容,以在下一步中建立建置工作。

使用 launch.json 自訂除錯

當您使用播放按鈕或 F5 進行除錯時,C++ 擴充功能會動態建立除錯組態。

在某些情況下,您會想要自訂您的除錯組態,例如指定要在執行階段傳遞至程式的引數。您可以在 launch.json 檔案中定義自訂除錯組態。

若要建立 launch.json,請從播放按鈕下拉式選單中選擇 [新增除錯組態]。

Add debug configuration play button menu

然後您會看到各種預先定義的除錯組態的下拉式選單。選擇 [g++ 建置並除錯作用中檔案]。

C++ debug configuration dropdown

VS Code 會建立一個 launch.json 檔案,看起來像這樣

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: g++ build and debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: g++ build active file"
    }
  ]
}

在上方的 JSON 中,program 指定您要除錯的程式。此處設定為作用中檔案資料夾 ${fileDirname} 和不含副檔名的作用中檔案名稱 ${fileBasenameNoExtension},如果 helloworld.cpp 是作用中檔案,則會是 helloworldargs 屬性是要在執行階段傳遞至程式的引數陣列。

預設情況下,C++ 擴充功能不會在您的原始程式碼中新增任何中斷點,且 stopAtEntry 值設定為 false

stopAtEntry 值變更為 true,以讓除錯工具在您開始除錯時停止在 main 方法上。

從現在開始,播放按鈕和 F5 將在啟動程式以進行除錯時從您的 launch.json 檔案讀取。

C/C++ 設定

如果您想要更進一步控制 C/C++ 擴充功能,您可以建立 c_cpp_properties.json 檔案,這可讓您變更設定,例如編譯器的路徑、包含路徑、C++ 標準 (預設為 C++17) 等等。

您可以透過從「命令面板」執行 [C/C++: 編輯組態 (UI)] 命令來檢視 C/C++ 組態 UI (⇧⌘P (Windows、Linux Ctrl+Shift+P))。

Command Palette

這會開啟 [C/C++ 組態] 頁面。當您在此處進行變更時,VS Code 會將其寫入 .vscode 資料夾中名為 c_cpp_properties.json 的檔案。

IntelliSense configuration window

只有當您的程式包含不在您的工作區或標準程式庫路徑中的標頭檔時,您才需要修改 [包含路徑] 設定。

Visual Studio Code 會將這些設定放在 .vscode/c_cpp_properties.json 中。如果您直接開啟該檔案,它應該看起來像這樣

{
  "configurations": [
    {
      "name": "Linux",
      "includePath": ["${workspaceFolder}/**"],
      "defines": [],
      "compilerPath": "/usr/bin/gcc",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "clang-x64"
    }
  ],
  "version": 4
}

重複使用您的 C++ 設定

VS Code 現在已設定為在 Linux 上使用 gcc。此組態適用於目前的工作區。若要重複使用此組態,只需將 JSON 檔案複製到新專案資料夾 (工作區) 中的 .vscode 資料夾,並視需要變更原始檔和可執行檔的名稱。

疑難排解

編譯器和連結錯誤

錯誤最常見的原因 (例如 undefined _mainattempting to link with file built for unknown-unsupported file format 等等) 發生在您開始建置或開始除錯時,helloworld.cpp 不是作用中檔案的情況下。這是因為編譯器嘗試編譯的不是原始程式碼,而是類似您的 launch.jsontasks.jsonc_cpp_properties.json 檔案。

後續步驟