1.1 安装编译器并验证
1.1 安装编译器并验证
这一节的目标很具体:在你自己的电脑上装好编译器,配好环境,然后亲手编译并运行第一个程序。
配套视频:C 语言从零开始 01|装编译器:MSYS2 + GCC,跑通 hello world(5 分钟,和下面的步骤一一对应)
学完这一节,你应该能够
写代码需要三个工具
写代码需要几个工具?三个,缺一个都不行。
| 工具 | 它干什么 | 常见例子 |
|---|---|---|
| 编辑器 | 就是写代码的地方,本质是个高级记事本 | VS Code、Vim、系统自带的记事本 |
| 编译器 | 把 C 源文件翻译成可执行文件 | GCC、Clang、MSVC |
| 终端 | 输入命令、对编译器发指令的窗口 | PowerShell、Terminal、bash |
编辑器只负责把字符存成文件,不关心这些字符是什么意思。所以你写完代码,它并不知道这段代码能不能跑。
编译器做的事叫翻译:读入你写的 C 文件,输出一个可执行文件(Windows 上的可执行文件是 exe)。exe 里面是机器指令,是计算机能直接执行的形式。
终端则是那个可以输入命令的窗口。在 Windows 上,我们用的是 PowerShell。它的作用是让你对编译器发指令:编译哪个文件、可执行文件叫什么名字。
C 不能双击运行
你的 C 语言代码只是文本。必须先编译,才能得到可执行文件——这是 C 与 Python、JavaScript 在学习体验上最大的不同。
另外别把这两个词搞混:终端是那个窗口,shell 是窗口里读你命令的程序(PowerShell、bash、zsh 都是 shell)。日常混用没关系,知道区别就行。
五种方案,你只需要看第一行
| 方案 | 系统 | 说明 |
|---|---|---|
| MSYS2 | Windows | 本教程用它,一行命令装好,生态最接近 Linux |
| WSL2 | Windows | 想顺便学 Linux |
| 包管理器 | Linux | apt install gcc 一行搞定 |
| Homebrew | macOS | xcode-select --install |
| 免安装版 | 无管理员权限 | 解压即用,手动配 PATH |
下面只展开 MSYS2 这一条路——本教程后面所有内容都基于它。
第 1 步 · 打开终端
先学会打开终端。 这一步单独拎出来,是因为很多人在这里就卡住——后面的命令再对,敲不进去也白搭。
右键开始按钮,选「终端」。


窗口上方写着 Windows PowerShell 的就是终端,Windows 都自带,不用额外装。

怎么粘贴命令:粘贴命令,右键和 Ctrl+V 都行,我更建议右键。
粘贴后要按回车
粘贴只是把命令放进窗口,按 回车 才真正执行。如果一行命令被拆成好几行显示,那是窗口自动换行,不影响执行。
第 2 步 · 安装 MSYS2
接下来装 MSYS2。安装包默认从境外下载,国内很容易卡住,所以这一步直接走国内镜像。
在 PowerShell 里输入这一条命令,回车:
curl.exe -L -o msys2.exe https://mirrors.tuna.tsinghua.edu.cn/msys2/distrib/msys2-x86_64-latest.exe ; .\msys2.exe install --confirm-command --root C:\msys64一条命令干两件事:前半段把安装包从清华镜像下到当前目录,分号后面那半段直接调用安装程序——--confirm-command 跳过向导,--root C:\msys64 把安装路径写死成默认值。
装的时候终端会刷一屏 [数字] 开头的日志,那是安装器自己的输出,不是报错;看到 Components installed successfully. 就说明装好了。
清华连不上?换中科大
把命令整条换成下面这条,其余步骤不变:
curl.exe -L -o msys2.exe https://mirrors.ustc.edu.cn/msys2/distrib/msys2-x86_64-latest.exe ; .\msys2.exe install --confirm-command --root C:\msys64两个地址都是镜像站 distrib 目录下的 latest.exe,永远指向最新安装包,不用自己挑带日期的文件名。
也可以用 winget
winget install --id MSYS2.MSYS2 -e 同样是一条命令,但它下载的是 winget 清单里写死的境外地址,winget source 只换索引、换不掉这个地址,所以本教程不把它作为默认路径。
为什么要保持默认路径
第 6 步要写 C:\msys64\ucrt64\bin。--root 已经把路径写死在这里,后面照抄即可。
第 3 步 · 认出正确的 UCRT64 窗口
装完之后,开始菜单里会多出五个 MSYS2 的图标:UCRT64、MSYS、MINGW64,还有两个 CLANG 开头的。名字很像,别点错。
我们要的是 UCRT64。 点进去。

怎么确认点对了?看窗口里第一行提示符:
你的名字@电脑名 UCRT64 ~出现 UCRT64 就对了。如果显示的是 MINGW64 或 MSYS,关掉,重新从开始菜单选 MSYS2 UCRT64。
为什么是 UCRT64
这几个窗口的区别是使用的运行时库不同。UCRT64 是官方当前推荐、也是本教程使用的那个,选它就行,不必深究。
第 4 步 · 更新系统
打开 UCRT64 之后,第一件事是更新。输入:
pacman -Syu它会先同步软件源,然后开始核心升级。由于 MSYS2 的核心组件被替换,必须重启终端才能继续。
如果第一遍就显示 :: Starting core system upgrade... there is nothing to do,说明核心组件已经是最新的,跳过重启,直接做第 5 步。
关掉这个窗口,重新打开 MSYS2 UCRT64,再输一遍:
pacman -Syu等它跑完,再输一遍:
pacman -Syu为什么要跑好几遍
第一遍只换了 pacman 自己和最核心的包;重启窗口后再跑,才能把其余依赖更新到位。只跑一遍就装 GCC,很容易出现 404 或依赖冲突。
什么时候算更新完
如果显示 there is nothing to do,就代表更新完毕,可以进入下一步了。
为什么不教换源(以及什么时候必须换)
mirror.msys2.org 不是一台服务器,而是一个跳转器(Mirrorbits),会按你的 IP 挑一台镜像。挑得好的时候直接给你清华或南大,速度够用,所以多数情况下不用改。
真被分到境外、下载慢得离谱时,才需要手工换——具体做法见文末「把源固定到清华」。
第 5 步 · 安装 GCC
现在装编译器和调试器:
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gdb它会列出需要安装的依赖包(下载约 120 MB、装完占 850 MB 左右),输入 Y 确认安装。
等它跑完,每行末尾都是 100%、没有 error,就代表安装完毕。
为什么连 gdb 一起装
gcc 负责把源码编译成 exe,gdb 是调试器。下一节配 launch.json 时,miDebuggerPath 要指向 C:/msys64/ucrt64/bin/gdb.exe——少装它,编辑器里按 F5 会报找不到调试器。右上角的「运行 C/C++ 文件」按钮仍然能用(它只调编译器),所以不装也能跑出 hello world,但调试功能是坏的。
这一步在下载什么
mingw-w64-ucrt-x86_64-gcc 是「UCRT64 运行时下的 GCC」——MSYS2 的包名把「目标平台 + 运行时 + 包名」写全了,所以你看到的是一个很长的名字;gdb 那个包同理。
第 6 步 · 把编译器写进环境变量
这一步是整个安装里最容易出错的地方,先花一分钟理解它在干什么。
编译器装好了,但系统还不知道它在哪
当你在终端敲 gcc 时,系统会按 Path 里列出的文件夹顺序,逐个去找 gcc.exe。找到了就运行,找不到就报「不是内部或外部命令」。
GCC 装在 C:\msys64\ucrt64\bin,但这个文件夹默认不在 Path 里。这一步就是告诉系统:去这个文件夹里也找找。
操作步骤
① 点击开始,输入「环境变量」,选「编辑系统环境变量」

② 在系统属性窗口里点「环境变量」

③ 窗口分成上下两块:上面是「用户变量」,下面是「系统变量」——找到用户变量里的 Path,双击打开

④ 选择「新建」,列表里会多出一个空行

⑤ 把路径写进去
C:\msys64\ucrt64\bin或者点击「浏览」找到该路径。

⑥ 一路点「确定」关闭三个窗口



| 用户变量 | 系统变量 | |
|---|---|---|
| 生效范围 | 只对你当前登录的账户 | 这台机器所有账户 |
| 修改权限 | 不需要管理员 | 通常需要管理员 |
| 建议 | 选这个 | 多人共用电脑时才用 |
gcc.exe 本身就在 bin 目录里。Path 指到文件夹(不是 .exe 文件),系统才会进去找。
改完必须关掉所有已打开的终端窗口
Path 只在终端启动时读取一次。已经开着的窗口还是旧配置——不只是 PowerShell,还包括 CMD、Windows Terminal 的每个标签页、VS Code 底部的终端。全关掉,再重新打开。
第 7 步 · 验证
重新开一个 PowerShell(不是 MSYS2 窗口),输入:
gcc --version出现版本号,就说明系统现在知道编译器在哪。 真实输出长这样:
gcc.exe (Rev6, Built by MSYS2 project) 16.2.0
Copyright (C) 2026 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.版本号数字不一样?
16.2.0 是录制时的版本,你装的时候很可能是更新的版本,这是正常的。只要第一行出现 gcc.exe (Rev... 字样,就说明装成功了。
报「不是内部或外部命令」怎么办
三种典型报错,都说明系统找不到 gcc:
gcc : 无法将“gcc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。'gcc' 不是内部或外部命令,也不是可运行的程序或批处理文件。bash: gcc: command not found回到第 6 步检查 Path 是否含 C:\msys64\ucrt64\bin,并确认已经关掉所有旧终端窗口。
第 8 步 · 写代码,编译,运行
① 先给代码安个家
mkdir D:\C_Code
cd D:\C_CodeD 盘里就有了一个叫 C_Code 的文件夹,并且你已经进到里面。
路径含中文行不行
本节演示用 D:\C_Code,实测可用。但如果你的工具链版本遇到编码问题(报错信息里出现乱码),换成纯英文路径(如 D:\c-code)即可,后续命令把路径替换掉就行。
② 把代码写进 hello.c
Set-Content hello.c '#include <stdio.h>','int main(void) {',' printf("hello, world\n");',' return 0;','}'然后查看文件内容,确认写进去了:
cat hello.c看到这五行就对了:
#include <stdio.h>
int main(void) {
printf("hello, world\n");
return 0;
}③ 编译
gcc hello.c -o hello没有任何输出,通常就是成功了——编译器不报喜,没消息就是好消息。想确认得更踏实,看 gcc 的退出码是不是 0(1.3 会讲)。
看一眼文件夹里多了什么:
ls列表里会多出一个 hello.exe,这就是编译器翻译出来的程序。
-o hello 是什么意思
告诉编译器「把结果输出成名叫 hello 的程序」。不写它的话,Windows 上会生成 a.exe,其他系统上生成 a.out。
④ 运行
.\hello屏幕上会打出:
hello, world看到这行字,环境就彻底打通了。
为什么要加 .\
运行当前目录里的程序要加 .\:PowerShell 不会在当前目录里找程序(cmd 会,这是两者的差别)。直接敲 hello 会被当成系统命令去找,找不到就报「无法将 hello 项识别为...」。
常见问题
| 现象 | 原因 | 解决 |
|---|---|---|
无法将“gcc”项识别为... | Path 未配置,或终端未重启 | 检查用户变量 Path 是否含 ...\ucrt64\bin;关掉所有终端重开 |
| 改了 Path 仍然报错 | 旧终端窗口没关 | 包括 VS Code 底部终端在内的所有窗口都要关掉 |
pacman 报 404 / unable to lock database | 首次未完整更新,或上次异常中断 | 重开 UCRT64,先跑几遍 pacman -Syu 再装 |
pacman -Syu 卡住不动 | 首次升级要下上百兆,且跳转器可能把你分到慢镜像 | 先等 3–5 分钟,长时间无变化再 Ctrl+C 重来;反复卡见下面「把源固定到清华」 |
| 下一节按 F5 报「找不到 gdb」 | 第 5 步只装了 gcc,没装 gdb | 回 UCRT64 补跑 pacman -S mingw-w64-ucrt-x86_64-gdb |
| 装完 MSYS2 找不到 UCRT64 图标 | 开始菜单缓存未刷新 | 搜索栏直接输 MSYS2 UCRT64 |
| 运行程序提示找不到命令 | PowerShell 下没加 .\ | 敲 .\hello |
编译报 hello.c.txt 相关错误 | 文件名多了 .txt 后缀 | 显示扩展名后重命名(资源管理器「查看」→「文件扩展名」) |
把源固定到清华
/etc/pacman.d/mirrorlist* 是 MSYS2 内部的写法,对应 Windows 上的 C:\msys64\etc\pacman.d\ 那个文件夹。不用去资源管理器里找,直接在 UCRT64 窗口里跑这一条:
sed -i "s#https\?://mirror.msys2.org/#https://mirrors.tuna.tsinghua.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*它把每个 mirrorlist 的第一行(官方跳转地址)替换成清华,其余各行不动。再跑 pacman -Syu,下载就改走清华了。
不想敲命令也行。在文件资源管理器的地址栏粘这一行回车:
C:\msys64\etc\pacman.d用记事本打开 mirrorlist.mingw 和 mirrorlist.msys,把第一行的 https://mirror.msys2.org/ 改成 https://mirrors.tuna.tsinghua.edu.cn/msys2/,保存即可。如果提示没有权限,就用管理员身份打开记事本再改。
旧版 MSYS2 的文件名不一样
2026 版把 mingw 各环境合并成了 mirrorlist.mingw 一个文件;更早的版本会拆成 mirrorlist.ucrt64、mirrorlist.mingw64、mirrorlist.clang64 等多个文件。改法完全一样,都是改第一行。上面的 sed 用的是 mirrorlist* 通配,两种布局都覆盖。
:::
术语小词典
| 词 | 一句话解释 |
|---|---|
| 终端 / Terminal | 那个可以敲命令的窗口 |
| shell | 窗口里真正读你命令的程序(PowerShell、bash、zsh) |
| Path | 一串文件夹路径,系统按它去找你敲的程序 |
| 环境变量 | 系统保存的一组配置,Path 只是其中一个 |
| 包管理器 | 命令行版的「应用商店」,如 winget、pacman、apt、dnf |
| UCRT64 | MSYS2 里的一个运行环境,也是本教程用的那个窗口 |
| MinGW-w64 | 让 GCC 能在 Windows 上用的工具链 |
| 可执行文件 | 编译产物,Windows 上是 .exe,其他系统上通常没有后缀 |
| gdb | 调试器,能一行行跑程序、查看变量的值;第 5 步和 gcc 一起装 |
练习
- 执行
gcc --version,把第一行记录到笔记里。 - 建一个属于自己的代码目录,进去后用
pwd(或Get-Location)确认位置。 - 把
printf里那句话改成你自己的名字,重新编译运行,确认改动生效。 - 故意把 Path 配错一次(比如少写
\bin),观察报错原文,再改回来。见过一次报错,比背十次定义有用。