Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第0.5章 C语言开发环境与工具

总述

在学习 C 语言之前,我们首先需要准备好开发工具。本教程选择的工具组合是:VSCode + Clang

你可能会注意到,市面上许多 C 语言教程使用的并不是这套组合。那么,我们为什么做出这个选择?

本章分为两大部分:先带你完成 Windows 和 macOS 两个平台上的开发环境搭建,再通过开发环境和工具科普梳理代码编辑器、编译器、C 语言标准以及工具选型背后的权衡——这些是你迟早会接触到的概念。


一、Windows 平台开发环境搭建

📦 开发工具百度网盘地址链接:https://pan.baidu.com/s/1ipTFXUcJ_isVz_sf9ncyzA?pwd=bkpg 提取码: bkpg

本链接包含了 LLVM-ClangCMakePython 的安装包,后续小节中提到的安装包均可从此处获取。

1.1 打开终端

Windows 11 打开终端的方式非常简单:右键点击任务栏上的 Win 图标(开始菜单图标),在弹出的菜单中选择**“终端”**,即可打开。

后续的所有命令行操作——编译、运行程序——都将在这个终端中完成。

1.2 下载并安装 LLVM-Clang

从上述网盘链接中下载 LLVM 安装包。下载完成后,运行安装程序。

⚠️ 重要:安装时务必勾选“Add LLVM to the system PATH“(将 LLVM 添加到系统 PATH)选项。 这个选项确保你可以在终端中直接输入 clang 命令。如果忘记勾选,后续需要手动配置环境变量,较为麻烦。

1.3 验证 Clang 安装

安装完成后,打开终端,输入以下命令验证是否安装成功:

clang --version

如果正常输出版本信息(包含 “clang version 22” 等字样),说明 Clang 编译器已安装成功。

1.4 安装 Python(lldb 调试器依赖)

本教程使用的 LLVM 22 中,lldb 调试器依赖 Python 3.11.x。 因此,你还需要额外安装 Python。

从 Python 官网(https://www.python.org/)下载 Python 3.11.x 版本的安装包。安装时务必勾选 “Add Python to PATH”

安装完成后验证:

python --version

应输出类似 Python 3.11.x 的版本信息。

1.5 安装 CMake(必需)

CMake 不是可选的——它是本教程后续项目构建的核心工具。 随着项目从单文件增长到多文件、再到引入第三方库,手动输入编译命令会变得越来越繁琐。CMake 让你用一份简洁的配置文件描述项目结构,然后自动生成对应平台的构建文件。

CMake 安装包同样可以从上述网盘链接中获取。下载后运行安装程序,安装时勾选 “Add CMake to the system PATH”

安装完成后验证:

cmake --version

如果正常输出版本号,说明 CMake 安装成功。

1.6 安装 VSCode

访问 VSCode 官网,下载 Windows 版本的 .exe 安装程序,运行后按提示完成安装。

1.7 安装 C/C++ Extension Pack

首次启动 VSCode 后,你需要安装 C/C++ 相关插件来获得语法高亮、代码补全、错误提示和调试支持。

点击 VSCode 左侧活动栏的“扩展“图标(或按 Ctrl+Shift+X),搜索 “C/C++ Extension Pack”,安装由 Microsoft 发布的这个扩展包。

C/C++ Extension Pack 是一个插件集合包,它一次性为你安装了:

  • C/C++ 核心扩展——语法高亮、代码补全、错误提示、调试支持
  • CMake Tools——CMake 项目的集成支持
  • C/C++ Themes——代码配色主题

VSCode C/C++ Extension Pack 安装截图

相比单独安装 “C/C++” 扩展,安装 Extension Pack 可以一并获得 CMake 等工具的集成支持,省去了逐个安装的麻烦。

1.8 验证编译环境

至此,Windows 上的 C 语言开发环境已经搭建完成。依次输入以下命令来确认各工具已正确安装:

# 确认 Clang 编译器
clang --version

# 确认 lldb 调试器
lldb --version

# 确认 Python
python --version

# 确认 CMake
cmake --version

每一条命令都应该输出对应的版本信息。如果某条命令提示 command not found,说明对应工具的安装步骤可能未成功,请回到相应小节重新操作。


二、macOS 平台开发环境搭建

2.1 打开终端

macOS 的终端可以通过以下方式打开:在“启动台 → 其他“中找到“终端(Terminal)“,或按 Cmd + 空格 搜索“终端”。

2.2 安装 Xcode Command Line Tools(含 Clang 编译器)

macOS 自带的默认编译器就是 Clang——但前提是你需要先安装 Xcode Command Line Tools。这是一个由 Apple 官方提供的命令行开发者工具包,包含了:

  • Clang 编译器(C/C++/Objective-C 前端)
  • LLVM 后端(代码优化与机器码生成)
  • make(构建自动化工具)
  • lldb(调试器)
  • C/C++ 标准库头文件(如 stdio.hstdlib.h 等)

安装方法:打开终端,输入以下命令:

xcode-select --install

系统会弹出安装确认对话框,点击“安装“,同意许可协议后等待下载完成即可。整个过程通常在几分钟到十几分钟之间,取决于网络速度。

注意: xcode-select --install 安装的是命令行工具包,体积约 1–2 GB。你不需要从 App Store 下载完整的 Xcode(体积超过 10 GB)。对 C 语言学习而言,Command Line Tools 已经完全够用。

2.3 安装 Homebrew

Homebrew 是 macOS 上最流行的软件包管理器。它的角色类似于 Linux 上的 aptyum——通过命令行即可搜索、安装、更新和卸载各种开源软件,而无需手动访问各个网站下载安装包。

打开终端,输入以下命令:

/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

这是 Homebrew 的国内镜像安装脚本,适合网络访问 GitHub 不稳定的用户。按提示操作即可——脚本会自动完成下载、安装和环境变量配置。

安装完成后,验证 Homebrew 是否可用:

brew --version

如果正常输出版本号(如 Homebrew 4.x.x),说明安装成功。

2.4 使用 Homebrew 安装 CMake(必需)

CMake 不是可选的——它是本教程后续项目构建的核心工具。

有了 Homebrew 之后,安装 CMake 只需要一行命令:

brew install cmake

安装完成后验证:

cmake --version

2.5 安装 VSCode

访问 VSCode 官网,下载 macOS 版本的 .dmg 文件,将 VSCode 拖入“应用程序“文件夹即可。

2.6 安装 C/C++ Extension Pack

首次启动 VSCode 后,你需要安装 C/C++ 相关插件来获得语法高亮、代码补全、错误提示和调试支持。

点击 VSCode 左侧活动栏的“扩展“图标(或按 Cmd+Shift+X),搜索 “C/C++ Extension Pack”,安装由 Microsoft 发布的这个扩展包。

C/C++ Extension Pack 是一个插件集合包,它一次性为你安装了:

  • C/C++ 核心扩展——语法高亮、代码补全、错误提示、调试支持
  • CMake Tools——CMake 项目的集成支持
  • C/C++ Themes——代码配色主题

相比单独安装 “C/C++” 扩展,安装 Extension Pack 可以一并获得 CMake 等工具的集成支持,省去了逐个安装的麻烦。

2.7 验证编译环境

至此,macOS 上的 C 语言开发环境已经搭建完成。打开终端,依次输入以下命令来确认各工具已正确安装:

# 确认 Clang 编译器
clang --version

# 确认 lldb 调试器
lldb --version

# 确认 CMake
cmake --version

每一条命令都应该输出对应的版本信息。如果某条命令提示 command not found,说明对应工具的安装步骤可能未成功,请回到相应小节重新操作。

接下来,你就可以进入下一章,编写并运行你的第一个 C 程序了。 如果对 Clang 命令行的基本用法还不太熟悉,可以直接翻到第一章末尾的“小贴士“——那里给出了你最需要掌握的第一个编译选项。


开发环境和工具科普

代码编辑器

从“记事本能写代码吗“说起

从技术上讲,你完全可以用 Windows 自带的记事本编写 C 语言代码。一个代码文件本质上就是一个纯文本文件(后缀为 .c),里面只有你敲入的字符,不包含任何特殊格式。

但问题在于:记事本不会给你任何帮助。它不会——

  • 用不同颜色区分关键字和变量(语法高亮
  • 在你漏掉分号时给出提醒(错误提示
  • 在你键入 prin 时自动补全为 printf代码补全
  • 帮你快速跳转到某个函数的定义处(代码导航

代码编辑器,就是为编写代码而专门设计的文本编辑器。它处理的依然是纯文本,但在此之上叠加了大量辅助功能,使你的编码效率获得数量级的提升。

Visual Studio Code(简称 VSCode),是当前全球使用最广泛的代码编辑器。它由微软开发,完全免费,开源,跨平台——在 Windows、macOS 和 Linux 上均可安装使用。

大部分教程用的其实是 Visual Studio(VS)

翻开市面上大多数 C/C++ 中文教材,你会发现它们几乎无一例外地使用 Visual Studio(注意,名字里没有 “Code” 这个词)。

Visual Studio(简称 VS)和 Visual Studio Code(简称 VSCode),虽然名字只相差一个单词,但它们是两个截然不同的产品

对比维度VSCodeVisual Studio (VS)
定位代码编辑器集成开发环境(IDE)
体积轻量,数百 MB重量级,十几 GB 起步
启动速度快,秒级启动较慢,需加载大量组件
内置编译器无,需手动安装自带微软 MSVC 编译器
内置调试器需安装插件自带功能完善的调试器
项目管理通过插件支持内置解决方案/项目体系
GUI 可视化设计不支持支持拖拽式窗口设计(Windows)
跨平台Windows / macOS / Linux 均可仅 Windows(Mac 版功能不完整)
插件生态极其丰富,几乎覆盖所有场景较丰富
免费完全免费社区版免费,企业版收费

代码编辑器 vs IDE:根本区别在哪?

代码编辑器(如 VSCode、Sublime Text、Vim)的核心任务只有一个:高效地编辑代码文本。你可以把它理解为一个“超级记事本“,专注于让你顺畅地书写和修改代码。至于编译、调试、项目管理这些环节,它本身并不内置,需要你手动安装插件或搭配外部工具来完成。

集成开发环境(IDE)(如 Visual Studio、CLion、Eclipse)则是一个“全家桶“。它将代码编辑、编译构建、调试、项目管理、性能分析、可视化界面设计等开发过程中涉及的几乎所有功能打包在一起,追求开箱即用的体验。

打个比方:

  • 代码编辑器像一套专业的厨师刀——轻便、锋利、灵活。但你需要自己准备锅、灶台和食材,也可以自由选择任何品牌的锅和灶具。
  • IDE 像一个集成厨房——刀架、炉灶、抽油烟机、蒸烤箱全部预装到位,按下开关就能开火烹饪。方便固然方便,但如果你想换一个不同品牌的灶台,恐怕就很难装进去了。

我们选择 VSCode 而不是 VS 的原因,可以归纳为以下四点:

  1. 轻量:你不需要为编写一个 hello.c 而下载安装十几个 GB 的软件。
  2. 跨平台兼容性:Windows、macOS、Linux 均可使用。VS 基本只适用于 Windows,而本教程需要兼顾使用不同操作系统的读者。
  3. 插件生态:在当下的 AI 工具浪潮中,VSCode 拥有目前最活跃的 AI 辅助编程插件生态;相比之下,VS 在这方面的进展要迟缓得多。
  4. 学习价值:IDE 替你隐藏了大量底层细节。使用 VSCode,你需要亲自配置编译器和构建流程——起初确实会多花一些功夫,但在这个过程中,你对整个工具链的理解会扎实许多。

需要提前说明的是:VSCode 在 C/C++ 初学者群体中有一个广为人知的外号——“劝退器”。

这个说法并非空穴来风。VSCode 本质上只是一个代码编辑器——它不附带编译器,不附带构建环境,没有开箱即用的 C/C++ 开发工具链。你需要自己去下载编译器(比如 Clang),自己在本地把环境配置好,自己学会如何用命令行编译和运行程序。

相比之下,VS 安装完成后,你就能直接点击“运行“按钮看到程序结果。因此,刚开始用 VSCode 学习 C 语言时,你可能会感到繁琐。这种感受是正常的——但每一个让你感到繁琐的步骤,背后都对应着一项你在真正掌握的工具链知识。当 IDE 替你一键完成了所有事情,你也就失去了理解“一键背后到底发生了什么“的机会。


编译器

编译器是什么?

你已经写好了一个 hello.c 文件,但计算机的“母语“只有 0 和 1 组成的机器语言——它并不认识 printf,也不认识 intreturn。你需要一个翻译,把人类能够读写的 C 语言代码,转换成计算机能够执行的机器指令。

这个翻译,就是编译器

LLVM 和 Clang:两个经常一起出现的名字

你可能经常看到 “LLVM” 和 “Clang” 这两个词被并列提及。它们之间是什么关系?

Clang 是一个编译器前端。所谓“前端“,指的是编译过程中负责“读懂“源代码的那个部分:它检查你的 C/C++ 代码是否符合语法规则,然后将代码转换成一种中间表示——你可以把它理解为一种“半成品“代码,已经完成了语法层面的处理,但还没有绑定到具体的硬件指令。

LLVM 是一个编译器后端框架。所谓“后端“,指的是接过 Clang 生成的“半成品“代码,进行优化,并最终翻译成特定 CPU 能够执行的机器指令的那个部分。

它们的分工可以理解为一条流水线:

C/C++ 源代码 → [ Clang:前端——读代码、检查语法、生成中间表示 ] → [ LLVM:后端——优化、生成机器码 ] → 可执行文件

Clang 是 LLVM 项目的一部分。 LLVM 项目起源于伊利诺伊大学的一个研究项目,经过多年发展,已成为业界最先进的编译器基础设施之一。而 Clang,则是这个项目中的 C/C++ 前端。

实际下载时你会注意到的: 当你搜索“下载 Clang“时,你会发现它并没有一个独立的“Clang 官网“。它的源代码托管在 LLVM 的 GitHub 仓库中——仓库名为 llvm-project,里面同时包含了 LLVM 后端和 Clang 前端的全部代码。很多场合也会直接称其为 LLVM-Clang

因此,如果你在搜索或阅读资料时看到 “llvm-project” 或 “llvm-clang” 这样的名称,不用困惑——它们指向的就是你需要的那个东西。

如果上面关于“前端“和“后端“的讨论你现在没有完全理解,完全不必担心。 对初学者而言,你只需要知道一件事:你写的 .c 文件,通过一个叫 clang 的命令就能编译成可执行程序。LLVM 和 Clang 之间的分工与协作,随着你学习的深入,会自然而然地变得清晰。

C/C++ 的三大主流编译器——以及它们带来的最大挑战

与 Java 或 Python 这类通常只有一个“官方实现“的语言不同,C/C++ 的世界在历史上形成了三大主流编译器:

编译器开发者主要平台特点
MSVC微软WindowsVisual Studio 自带,Windows 平台上的事实标准
GCCGNU 社区Linux / macOSLinux 系统的默认编译器,历史最为悠久,几乎无处不在
ClangLLVM 社区所有平台三大编译器中诞生最晚,但进步最快,错误提示最为友好

这就是 C/C++ 学习中最常遇到的挑战之一:同一种语言,多个不同的编译器实现。

虽然它们都遵循 C 语言标准(后面会详述),但在具体细节上各有各的处理方式:

  • 同一个关键字,MSVC 可能提供了某种扩展写法,而 GCC 没有。
  • 同一个未定义行为,在 GCC 下能够运行,在 MSVC 下可能直接崩溃。
  • 同一个项目,用 A 编译器编译顺利通过,用 B 编译器却报出一连串警告甚至错误。
  • 每个编译器还有自己的一套命令行参数体系,互不通用。

因此,当你从网上下载了一个 C 语言项目,却发现按照教程无法编译通过时,首先要排查的就是:你是否使用了和教程不同的编译器。


C语言标准

既然编译器由不同的团队各自开发,每家都可以有自己的实现方式,那么靠什么来保证“C 语言代码“在不同编译器下的行为基本一致?

这就是语言标准的角色。

C/C++ 标准是一份极为严谨的技术文档,它详细规定了:

  • C 语言包含哪些关键字(如 intifreturn
  • 语法规则是什么(如函数如何定义、循环如何书写)
  • 标准库中有哪些函数,每个函数的行为应当如何(如 printf 应该怎样输出)

这两门语言由 ISO 下属的不同工作组维护:WG14 负责 C,WG21 负责 C++。工作组成员来自产业界和学术界,会通过提案、讨论和投票推进各自语言标准。虽然 C 与 C++ 联系紧密,但不存在一个统一决定两门语言规则的“C/C++ 标准委员会“。

C 语言标准的主要版本:

标准发布年份俗称重要变化
C89 / C901989/1990ANSI C第一个正式标准,奠定了 C 语言的基石
C991999增加了// 单行注释、变长数组等
C112011增加了多线程支持、_Generic 泛型选择等
C172018主要是缺陷修复,没有新增语言特性
C232024当前标准,引入了多项现代语言特性

一个关键的认知:标准委员会和编译器开发者是两批不同的人。

标准委员会负责撰写文档,规定“C 语言应该是什么样子“。 编译器开发者(微软、GCC 团队、LLVM 社区)负责编写软件,将这份标准实现为能够实际使用的编译器

正因为如此,你会在实践中发现:新标准发布后,编译器并不会立刻 100% 支持其中的所有特性。不同编译器对新特性的跟进速度也不相同——某个 C23 特性可能 Clang 已经支持了,而 MSVC 尚在追赶之中。

这个“标准与实现之间的时间差“,是 C/C++ 编程中需要持续留意的一个现实。

同样重要的是:标准委员会只负责说明“C 语言应该是什么样的“,但“如何做到“是各家编译器自己的事情。

语言标准是一份文档,它不是可执行的代码。标准规定了“应该怎样“,但每家的具体做法可以不同

  • 标准规定 int 必须覆盖的最小取值范围以及各整数类型之间的大小关系,但不规定它必须恰好是 32 位;具体宽度、对象表示和部分运算细节由实现决定
  • 标准规定标准库中必须包含 printf — 但 MSVC、GCC、Clang 三家对 printf 的底层实现代码,是三套完全不同的工程方案

这就意味着:相同的语法、相同的库函数,三家编译器在底层的处理方式可能截然不同。 一个程序在 Clang 下运行正常,换用 GCC 编译后行为可能有所差异;再换 MSVC 编译,又可能是另一种结果。这不是 bug,这是 C/C++ 生态的客观现实。

理解这一点对于学习 C 语言至关重要:你学习的核心是 C 语言本身,而不是某一个具体的编译器。但由于你必须通过某个编译器来实际运行代码,因此你同时也在和这个编译器的具体实现打交道。将“语言标准规定了什么“和“编译器具体做了什么“区分清楚,是 C 语言学习中一项重要的思维习惯。


为什么选择 VSCode + Clang

为什么选用 Clang?

在三大主流编译器中,我们选择 Clang。以下是主要理由:

1. 真正意义上的跨平台编译器

这是 Clang 最突出的优势。GCC 在 Windows 上虽然可以通过 MinGW 等工具使用,但那本质上是移植版本,其行为与 Linux 上的原生 GCC 并不完全一致。MSVC 则几乎只能在 Windows 上使用。

Clang 在 Windows、macOS、Linux 三大平台上都可以使用,核心命令行风格也高度一致。不过,不同平台仍然使用各自的 ABI、系统库、链接器和目标文件格式,因此“同一个 Clang“不代表生成结果或所有细节完全相同。教程中学习的常用命令可以迁移,平台差异仍需保留意识。

事实上,macOS 自带的默认编译器(在安装 Xcode Command Line Tools 之后)就是 Clang——它在终端中伪装成了 gcc 这个名字,但本质就是 Clang。

我们选择了一条需要更多投入的路

看到这里,你应该已经意识到了:VSCode + Clang 这套组合,没有个“一键编译运行“的按钮

安装好 VS 之后,你写好代码,点击绿色的运行按钮,程序就跑起来了——整个过程你甚至不需要知道“编译器“三个字的存在。但在我们的环境中,你需要:

  1. 打开终端
  2. 手动输入 clang hello.c -o hello 这样的命令来编译
  3. 再输入 ./hello(Windows 上是 hello.exe)来运行

这对初学者而言,不是额外增加了入门的难度吗?

坦率地说,是的。这是有意为之的选择。

C 语言——以及 C++——从来不是那种“拖拽一个控件就能做出东西“的高层语言。它们被设计出来的目的,就是用来写操作系统内核、写设备驱动、写数据库引擎——直接与底层硬件和操作系统打交道。你写的每一行 C 代码,最终都会变成 CPU 执行的机器指令;你调用的每一个函数,最终都会经由操作系统的系统调用去操作真实的内存和文件。

因此,从一开始就建立起对底层环节的认知,并非可有可无——它是 C 语言的基本功。 编译是什么?命令行怎么使用?编译器在按下回车键之后到底做了哪些事情?这些不是“进阶话题“,而是 C 语言学习的题中应有之义。

从另一个角度来看一个颇为常见的现象:有人在 VS 中学习了相当长时间的 C 语言,代码也写得不错,但当你问他——

  • “你用的什么编译器?”——他回答:“VS。”
  • “那 MSVC 是什么?”——他说:“没听过。”

这对于一个学习系统级语言的人来说,是一个值得反思的现象。VS 是一个 IDE(集成开发环境),不是一个编译器。藏在 VS 内部、真正负责编译代码的,是 MSVC。学了那么久的 C 语言,却对自己代码的编译过程缺乏最基本的了解——这正是 IDE 过度封装所带来的代价。

我们选择这条需要更多投入的路,不是因为 VSCode + Clang 比 VS 更方便,而是因为它让你能看清每一步在发生什么。当你在终端里亲手输入 clang 命令,亲眼看到 hello.c 变成一个可以运行的 hello.exe 时——你知道这中间发生了什么,你知道是谁在做这件事。

这份认知,会贯穿你的整个 C/C++ 学习生涯。