Visual Studio Code 構建 C/C++ 開發環境
1. 安裝 MinGW Distro / MinGW / GNU GCC 中的任何一款 (其各類安裝文件分類為:x86_64 為64位版,i686 為32位版。win32 為Windows版,posix 為Windows+Linux版。sjlj 為傳統穩定版,seh 為高速版。所以,一般下載 x86_64-posix-seh 文件即可),( Windows 下的 VS Code 暫不支持 CLang )。
2. 安裝 VS Code
3. Ctrl + Shift + X 安裝 C/C++ (cpptools) 插件

4. Ctrl + Shift + X 安裝 Code Runner 插件

5. 重啟 VS Code,讓安裝的插件生效
6. 在操作系統中新建一個工程目錄,如 “cppProject”,然后啟動 VS Code,打開這個空目錄
7. 用 VS Code 在 cppProject 目錄新建一個源文件 hello.cpp

8. 添加頭文件索引路徑
在 hello.cpp 中,你會發現 include 頭文件那一行下面有綠色的波浪線,代表 VS Code 的 C/C++ 插件找不到頭文件的相應路徑。 將鼠標移到這一行點擊,會出現一個提示的黃色小燈泡符號,點擊它,然后點擊“Edit "includePath" setting”按鈕, 將生成並打開 c_cpp_properties.json 文件,編輯這個json文件,添加 C/C++ 頭文件的路徑進去。 這里 MinGW 的頭文件路徑為: “C:/MinGW/include/*”,將它添加到“includePath”和"browse/path"變量中。

{
"configurations": [
{
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
]
},
{
"name": "Linux",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"C:/MinGW/include",
"${workspaceRoot}"
],
"defines": [
"_DEBUG",
"UNICODE"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/MinGW/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 3
}
另外在 tasks.json 中的 "tasks/args" 中加入 "--target=x86_64-w64-mingw"。
9. 設置編譯環境 (安裝了 Code Runner插件 的話,這個設置就不再起作用)
在 VS Code 中點擊 hello.cpp 回到 hello.cpp 文件,調用快捷鍵 Ctrl+Shift+B 構建可執行文件。 此時 VS Code 會報錯,在 VS Code 的頂欄顯示“No task runner configured”,你只需要點擊右邊的藍色按鈕“Configure task runner”來生成編輯 tasks.json 即可。 選擇后會創建並打開一個 tasks.json 的配置文件, 修改其中的 command 和 args 變量並保存:

"command": "g++ "
"args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}.exe", "--target=x86_64-w64-mingw", "-std=c++17" ]
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
// "command": "echo Hello",
"command": "g++ ", // 如果用MinGW,編譯C用gcc,編譯c++用g++。如果用CLang,編譯"clang++", //
// "args": ["-g", "${file}", "-o", "${workspaceRoot}/hello.exe"],
"args": [
"-g", // 生成和調試有關的信息
"${file}",
"-o", // 指定輸出文件名,不加該參數則默認輸出a.exe
"${fileDirname}/${fileBasenameNoExtension}.exe",
"-c -fexec-charset=GBK -finput-charset=UTF-8",
"-Og",
// "-Wall", // 開啟額外警告
// "-static-libgcc", // 靜態鏈接
"-fcolor-diagnostics",
"--target=x86_64-w64-mingw", // 默認target為msvc,不加這一條就會找不到頭文件
"-std=c++17" // c++1z即c++17,C++語言最新標准為c17
], // 編譯命令參數
"group": {
"kind": "build",
"isDefault": true // 設為false可做到一個tasks.json配置多個編譯指令,需要自己修改本文件
}
}
]
}
10. 設置編譯等環境
點擊“文件/首選項/設置”菜單,修改 settings.json 配置文件, 在左側的“默認設置”下找到“Run Code configuration”下的 "code-runner.executorMap" ,點擊其左側的“筆”圖標,選擇“在設置中替換”,將內容復制到右側的“用戶設置”中,修改其中的 "c" / "cpp" 項,使其支持 中文 和 C++17 標准。

11. 增加對 C++17 標准的支持
GNU GCC 7.2 直接支持 C++11 / C++14 標准,無需進行任何修改。如果需要支持 C++17 標准的話,則需要修改“用戶設置”中的 "c" / "cpp" 項,加入“-std=c++17”。
"cpp": "cd $dir && g++ -std=c++17 $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt"

{
"code-runner.executorMap": {
"javascript": "node",
"java": "cd $dir && javac $fileName && java $fileNameWithoutExt",
"c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"cpp": "cd $dir && g++ -std=c++17 $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"objective-c": "cd $dir && gcc -framework Cocoa $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"php": "php",
"python": "python",
"perl": "perl",
"perl6": "perl6",
"ruby": "ruby",
"go": "go run",
"lua": "lua",
"groovy": "groovy",
"powershell": "powershell -ExecutionPolicy ByPass -File",
"bat": "cmd /c",
"shellscript": "bash",
"fsharp": "fsi",
"csharp": "scriptcs",
"vbscript": "cscript //Nologo",
"typescript": "ts-node",
"coffeescript": "coffee",
"scala": "scala",
"swift": "swift",
"julia": "julia",
"crystal": "crystal",
"ocaml": "ocaml",
"r": "Rscript",
"applescript": "osascript",
"clojure": "lein exec",
"haxe": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt",
"rust": "cd $dir && rustc $fileName && $dir$fileNameWithoutExt",
"racket": "racket",
"ahk": "autohotkey",
"autoit": "autoit3",
"dart": "dart",
"pascal": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt",
"d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt",
"haskell": "runhaskell",
"nim": "nim compile --verbosity:0 --hints:off --run"
}
}
12. 對 中文漢字 的支持
VS Code 默認使用 UTF-8 編輯源程序並編譯成 UTF-8 的程序,因此,在 VS Code 中編輯編譯的程序在 VS Code 中運行不會出現亂碼。
但是,Windows 下的 命令提示符 和 PowerShell 的代碼頁默認為 GBK ,因此在它們窗口下直接運行程序,其中的中文漢字會變成亂碼。解決方法有兩種:
方法一,在窗口下運行以下命令,修改運行窗口的代碼頁
chcp 65001 # 就是換成UTF-8代碼頁,然后再運行程序
chcp 936 # 可以換回默認的GBK,
chcp 437 #是美國英語
方法二,修改程序的編碼
打開源程序窗口,點擊窗口右下角的編碼,例如“UTF-8”,選擇“通過編碼重新打開”下的“Chinese (GBK)”,將編碼變成 GBK ,即可以修改源程序的編碼。
再在11步中的“用戶設置”中的 "c" / "cpp" 項,加入“-fexec-charset=GBK”,編譯后程序為 GBK 編碼,它可以在默認的 命令提示符 窗口運行,但是在 VS Code 里面運行會出現亂碼。
"cpp": "cd $dir && g++ -fexec-charset=GBK -std=c++17 $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt"
13. 設置運行環境
打開 launch.json 的配置文件, 修改其中的 program 和 miDebuggerPath 變量並保存:

"program": "${workspaceFolder}/${fileBasenameNoExtension}.exe"
"miDebuggerPath": "gdb.exe"
{
// 使用 IntelliSense 了解相關屬性。
// 懸停以查看現有屬性的描述。
// 欲了解更多信息,請訪問: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch", // 配置名稱,將會在啟動配置的下拉菜單中顯示
"type": "cppdbg", // 配置類型,這里只能為cppdbg
"request": "launch", // 請求配置類型,可以為launch(啟動)或attach(附加)
"program": "${workspaceFolder}/${fileBasenameNoExtension}.exe", // 將要進行調試的程序的路徑
// "program": "enter program name, for example ${workspaceFolder}/a.exe",
// "program": "${fileDirname}/${fileBasenameNoExtension}.exe", // 將要進行調試的程序的路徑
"args": [], // 程序調試時傳遞給程序的命令行參數,一般設為空即可
"stopAtEntry": false, // 設為true時程序將暫停在程序入口處
"cwd": "${workspaceFolder}", // 調試程序時的工作目錄
"environment": [],
"externalConsole": true, // 調試時是否顯示控制台窗口,一般設置為true顯示控制台
"MIMode": "gdb", // 指定連接的調試器,可以為gdb或lldb。但目前lldb在windows下沒有預編譯好的版本。
// "miDebuggerPath": "/path/to/gdb", // 調試器路徑。
"miDebuggerPath": "gdb.exe", // 調試器路徑。
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
// "preLaunchTask": "Compile" // 調試會話開始前執行的任務,一般為編譯程序。與tasks.json的taskName相對應
]
}
14. 點擊右上角的 三角 圖標,運行程序
15.測試代碼
C語言測試代碼:
#include <stdio.h> void swap(int* pa, int* pb) { *pa = *pa ^ *pb; *pb = *pa ^ *pb; *pa = *pa ^ *pb; } int main() { int a = 5, b = 8; printf("交換前:\ta = %d, b = %d\n", a, b); swap(&a, &b); printf("交換后:\ta = %d, b = %d\n", a, b); return 0; }
C++11語言測試代碼:
#include <iostream> #include <iomanip> // std::setw #include <vector> // 一維數組 輸出 楊輝三角形 int main() { using std::cout; using std::endl; using std::setw; using std::vector; constexpr size_t Line = 16; constexpr unsigned W = 5; size_t i, j; int n[Line+1]; cout << "\t\tPascal 三角形\n" << endl; cout << setw(W) << (n[1] = 1) << endl; for (i = 2; i != Line+1; ++i) { cout << setw(W) << (n[i] = 1); for (j = i-1; j != 1; --j) cout << setw(W) << (n[j] += n[j-1]); cout << setw(W) << n[1] << endl; } cout << endl << endl; using std::begin; using std::end; cout << setw(W) << (n[1] = 1) << endl; for (int *pl = begin(n)+2; pl != end(n); ++pl) { cout << setw(W) << (*pl = 1); for (int *pr = pl-1; pr != begin(n)+1; --pr) cout << setw(W) << (*pr += *(pr-1)); cout << setw(W) << n[1] << endl; } cout << endl << endl; int nn[Line] = {0}, t; bool beg = true; for (auto ll : nn) { beg = true; for (auto &mm : nn) if (beg && mm == 1) { cout << setw(W) << (t = mm = 1); beg = false; } else if (mm == 0) { cout << setw(W) << (mm = 1) << endl; break; } else { cout << setw(W) << (mm += t); t = mm-t; } } cout << endl << endl; vector<unsigned> v(Line, 0); cout << setw(W) << (v[0] = 1) << endl; for (i = 1; i != Line; ++i) { cout << setw(W) << (v[i] = 1); for (j = i-1; j != 0; --j) cout << setw(W) << (v[j] += v[j-1]); cout << setw(W) << v[0] << endl; } cout << endl << endl; for (auto &ll : v) { ll = 0; beg = true; for (auto &mm : v) if (beg && mm == 1) { cout << setw(W) << (t = mm = 1); beg = false; } else if (mm == 0) { cout << setw(W) << (mm = 1) << endl; break; } else { cout << setw(W) << (mm += t); t = mm-t; } } cout << endl << endl; cout << setw(W) << (v[0] = 1) << endl; for (vector<unsigned>::iterator it = v.begin()+1; it != v.end(); ++it) { cout << setw(W) << (*it = 1); for (vector<unsigned>::reverse_iterator rit(it); rit != v.rend()-1; ++rit) cout << setw(W) << (*rit += *(rit+1)); cout << setw(W) << *(v.cbegin()) << endl; } cout << endl << endl; return 0; }
C++11語言shared_ptr測試代碼:
#include <iostream> #include <memory> // for std::shared_ptr class Resource { public: Resource() { std::cout << "Resource acquired\n"; } ~Resource() { std::cout << "Resource destroyed\n"; } }; int main() { // allocate a Resource object and have it owned by std::shared_ptr Resource *res = new Resource; std::shared_ptr<Resource> ptr1(res); { std::shared_ptr<Resource> ptr2(ptr1); // use copy initialization to make another std::shared_ptr pointing to the same thing // std::shared_ptr<Resource> ptr2(res); // create ptr2 directly from res (instead of ptr1) std::cout << "Killing one shared pointer\n"; } // ptr2 goes out of scope here, but nothing happens std::cout << "Killing another shared pointer\n"; return 0; } // ptr1 goes out of scope here, and the allocated Resource is destroyed
C++17語言測試代碼:
// 引用自: http://www.bfilipek.com/2017/09/cpp17-details-utils.html #include <string> #include <iostream> #include <any> #include <map> int main() { auto a = std::any(12); // set any value: a = std::string("你好!"); a = 16; // reading a value: // we can read it as int std::cout << std::any_cast<int>(a) << '\n'; // but not as string: try { std::cout << std::any_cast<std::string>(a) << '\n'; } catch(const std::bad_any_cast& e) { std::cout << e.what() << '\n'; } // reset and check if it contains any value: a.reset(); if (!a.has_value()) { std::cout << "a 是空的!" << "\n"; } // you can use it in a container: std::map<std::string, std::any> m; m["integer"] = 10; m["string"] = std::string("你好,親"); m["float"] = 1.0f; for (auto &[key, val] : m) { if (val.type() == typeid(int)) std::cout << "int: " << std::any_cast<int>(val) << "\n"; else if (val.type() == typeid(std::string)) std::cout << "string: " << std::any_cast<std::string>(val) << "\n"; else if (val.type() == typeid(float)) std::cout << "float: " << std::any_cast<float>(val) << "\n"; } }
參考文獻:
https://code.visualstudio.com/docs/languages/cpp
https://blogs.msdn.microsoft.com/c/2016/04/18/visual-studio-code的cc擴展功能/
