Vscode 編譯調試 C 代碼#
由於 vscode 只是一个文本編輯器,因此需要配置 task.json
和 launch.json
來完成編譯和調試的工作。(筆者的 C 環境基於 WSL 2(Ubuntu-20.04)搭建)
task.json
如下:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build C Program",
"type": "shell",
"command": "gcc",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
}
]
}
-
version:指定配置格式版本,當前僅支持
"2.0.0"
。 -
tasks:任務數組,每個元素對應一個可執行任務。
-
label:任務名稱,用於引用(如
preLaunchTask
)和在 UI 列表中顯示。 -
type:任務類型,常見值
"shell"
(在 shell 中運行)或"process"
(直接啟動可執行文件)。 -
command:要執行的命令或程序名稱。
-
args:傳遞給命令的參數列表,可使用內置變量插值。
"-g"
:生成調試符號,便於 GDB 等調試器進行源碼級調試。"${file}"
:當前活動編輯器中打開的文件的完整路徑(如/home/user/main.c
)。"-o"
:GCC 的輸出重定向選項,指定後續輸出文件路徑。"${fileDirname}/${fileBasenameNoExtension}"
:將可執行文件輸出到源文件同目錄,文件名與源文件同名但無擴展名(如輸出/home/user/main
)。
-
group:將任務歸類(如
build
、test
),並可標記為默認組內任務。 -
problemMatcher:指定如何解析命令輸出,將編譯器錯誤 / 警告映射到 “問題” 面板。
launch.json
如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "WSL Debug C",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"miDebuggerArgs": "--nx",
"preLaunchTask": "Build C Program"
}
]
}
C 語言作用域#
作用域是程序中定義的變量所存在的區域,超出該區域後變量就不能被訪問。C 語言的變量有三種:
- 在函數內部的局部變量
- 在所有函數外部的全局變量
- 在形式參數的函數參數定義
1 局部變量#
在某個函數或者區塊內部聲明的變量稱為局部變量。他們只能被該函數或代碼區塊內部的語句訪問,在函數或區塊外部是不可知的。
2 全局變量#
全局變量是定義在函數外部,通常是在程序的頂部。全局變量在整個程序生命週期內都是有效的,在任意的函數內部能訪問全局變量。全局變量可以被任何函數訪問。也就是說,全局變量在聲明後整個程序中都是可用的。
如果局部變量和全局變量的名字相同的話,在函數內優先使用局部變量。
3 形式參數#
函數的參數,形式參數,被當作該函數內的局部變量,如果與全局變量同名它們會優先使用。
指針#
指針即為內存地址,指針變量是用來存放內存地址的變量,使用前必須聲明。
type *var_name;
type
為指針的基類型,var_name
為指針變量的名稱,以下是有效的指針聲明:
int *ip; /* 一個整型的指針 */
double *dp; /* 一個 double 型的指針 */
float *fp; /* 一個浮點型的指針 */
char *ch; /* 一個字符型的指針 */
不同類型的指針對應的指針的值的類型是相同的,都為代表內存地址的十六進制數。不同類型的指針的區別為指針指向的變量或常數的數據類型不同。
1 指針使用方法#
定義一個指針變量,把變量的地址賦給指針,訪問指針變量中的地址。
#include <stdio.h>
int main ()
{
int var = 20; /* 實際變量的聲明 */
int *ip; /* 指針變量的聲明 */
ip = &var; /* 在指針變量中存儲 var 的地址 */
printf("var 變量的地址: %p\n", &var );
/* 在指針變量中存儲的地址 */
printf("ip 變量存儲的地址: %p\n", ip );
/* 使用指針訪問值 */
printf("*ip 變量的值: %d\n", *ip );
return 0;
}
//參考菜鳥教程
2 NULL 指針#
指針變量聲明的時候,如果沒有確切的地址幅值,則可為指針變量賦一個 NULL,此時該指針被稱為空指針。