第一章:初识计算机语言
1.1 什么是计算机语言?
- 计算机本质上就是一台按照指令工作的电子设备,如:
我们对计算机说:“计算两个数的和”,计算机其实并不能直接理解这句话。

- 计算机中的 CPU 最终能够执行的是
机器指令,如:10110000 01100001 ...。
提醒
机器指令:由二进制编码表示的指令,即:机器语言。

- 如果所有的程序都需要人类直接编写二进制指令,程序开发将会变得非常困难;于是,人类设计出了各种更加容易表达算法和逻辑的语言,即:计算机语言。
提醒
计算机语言 是 人与计算机 之间进行 信息表达 和 程序控制 的一套 形式化语言 。

- 对于我们学习编程而言,最重要的一类计算机语言就是编程语言,如:C、C++、Java 等。
提醒
掌握编程语言就能使用计算机解决实际问题,即:编程语言 → 表达算法和逻辑 → 计算机理解并执行 → 解决实际问题。

1.2 自然语言 VS 计算机语言
- 自然语言非常灵活,如:
帮我把这个文件打开。即使表达得不完全准确,人通常也能理解。
提醒
- ① 自然语言:灵活、宽松,更接近人类思维。
- ② 自然语言允许表达不完全正确,但人仍能理解并完成任务,这正体现了自然语言的灵活性和强大的人类理解能力。

- 计算机语言要求更加严格,如:C 语言中的
printf("Hello World\n");少一个;就会导致编译失败。
提醒
- ① 计算机语言:严格、精确,更接近机器思维。
- ② 计算机只能严格按照规则理解和执行程序,任何细微的错误都可能导致编译失败或运行出错。

自然语言和计算机语言的区别和联系,如下所示:
| 语言类别 | 特点 |
|---|---|
| 自然语言 | 💬 灵活多样,表达自由。 |
| 🤝 容错性高,不必完全正确。 | |
| 🧠 依赖上下文、经验和常识理解。 | |
| 👥 面向人类交流。 | |
| 计算机语言 | 📏 规则严格,必须完全正确。 |
| 🚫 容错性低,任何错误都可能导致失败。 | |
| 🔍 依赖编译器或解释器的严格检查。 | |
| ⚙️ 面向机器执行。 |
自然语言和计算机语言的共同目标,如下所示:
提醒
用清晰的方法表达思想,让对方(人或计算机)理解并完成任务!

1.3 为什么要学习计算机语言?
- 【问】现在的软件已经这么多了,为什么还需要学习编程语言?
- 【答】因为使用计算机和控制计算机,是两个不同的层次。
点我查看具体细节
- ① 普通用户 VS 程序员,如下所示:
| 用户类别 | 描述 |
|---|---|
| 普通用户 | 🌐 使用浏览器 |
| 📄 使用办公软件 | |
| 💬 使用微信 | |
| 🗄️ 使用数据库软件 | |
| ➕ …… | |
| 程序员 | 🛠️ 开发浏览器 |
| 💻 开发操作系统 | |
| 🗃️ 开发数据库 | |
| 🎮 开发游戏 | |
| 📱 开发应用软件 | |
| ➕ …… |
- ② 学习编程语言,就是学习如何把自己的想法转化为计算机能够执行的程序。
1.4 学习计算机语言到底在学习什么?
- 1️⃣ 从表面看,我们学习的是计算机语言的语法等,如:if、for、while、int、printf 等。

- 2️⃣ 其实,我们真正学习的是:问题 --> 分析 --> 抽象 --> 算法 --> 数据结构 --> 程序 --> 计算机执行。

- 3️⃣ 换言之,学习计算机语言不仅仅在学习语法等,更重要的是培养:逻辑思维,抽象能力、自动化能力。

1.5 计算机语言的发展简史
1.5.1 概述
- 计算机语言的发展,本质上在解决一个问题:
怎样让人更容易地控制计算机?。 - 计算机语言的发展,可以大致理解为:
机器语言 --> 汇编语言 --> 高级语言。
1.5.2 机器语言(相当于人类的石器时代)
- 1946 年 2 月 14 日,世界上第一台计算机
ENIAC诞生,使用的是最原始的穿透卡片。

- 上述使用的是
二进制代码表示的语言,和人类语言差别极大,被称为机器语言,如下所示:
txt
0000,0000,000000010000 代表 LOAD A, 16
0000,0001,000000000001 代表 LOAD B, 1
0001,0001,000000010000 代表 STORE B, 161
2
3
2
3
机器语言的优缺点,如下所示:
| 优缺点 | 描述 |
|---|---|
| 优点 | ✅️ CPU 可直接执行,无需翻译。 |
| ✅️ 执行效率高,硬件控制精确。 | |
| 缺点 | ❌️ 难写:只能使用二进制指令。 |
| ❌️ 难读:代码含义不直观。 | |
| ❌️ 难调试:错误难以定位。 | |
| ❌️ 难维护:修改成本高。 | |
| ❌️ 不可移植:依赖具体 CPU 架构。 | |
| ❌️ 学习困难:需要熟悉 CPU 和硬件细节。 |
- 不同类型(CPU 架构,如:x86_64、arm 等)的处理器有不同的机器语言指令集,指令集架构(ISA)决定了机器语言的具体形式。
提醒
机器语言 与特定硬件架构紧密相关,机器语言程序几乎没有可移植性!!!

1.5.3 汇编语言(相当于人类的青铜&铁器时代)
汇编语言使用助记符代替二进制操作码,使程序更易于人类编写和理解。

- 为了避免直接记忆,人类开始给机器指令起名字,如下所示:
txt
MOV AL, 5 ; # 10110000 00000101 ; 把数字 5 放入 AL 寄存器
ADD AL, 3 ; # 00000100 00000011 ; 把数字 3 加到 AL 寄存器中1
2
2
汇编语言的优缺点,如下所示:
| 优缺点 | 描述 |
|---|---|
| 优点 | ✅️ 比机器语言直观:使用 ADD 、 MOV 等助记符。 |
| ✅️ 执行效率高:可充分利用 CPU 指令。 | |
| ✅ 硬件控制精确:可直接操作寄存器和内存 | |
| ✅ 便于局部优化:适合优化关键代码。 | |
| 缺点 | ❌ 抽象层次低:复杂功能需要大量指令。 |
| ❌ 难开发:代码量大,容易出错。 | |
| ❌ 难调试和维护:需关注寄存器、内存等细节。 | |
| ❌ 学习困难:需要理解 CPU 和硬件原理。 | |
| ❌ 不可移植:依赖具体 CPU 架构。 |
汇编语言目前仍然应用于工业电子编程领域、软件的加密解密、计算机病毒分析等。
提醒
汇编语言 是 编程语言 的拓荒年代,它非常底层,直接和计算机硬件打交道,开发效率低,学习成本高。

1.5.4 高级语言
高级语言是一种接近于人们使用习惯的程序设计语言。高级语言允许程序员使用接近日常英语的指令来编写程序,程序中的符号和算式和日常使用的数学公式差不多,接近于自然语言和数学语言,容易被人们掌握。

- 高级语言
独立于计算机硬件,有一定的通用性;计算机不能直接识别和执行用高级语言编写的程序,需要使用编译器或解释器转换为机器语言,才能被计算机识别和执行。

高级语言的优缺点,如下所示:
| 优缺点 | 描述 |
|---|---|
| 优点 | ✅ 易读易写:语法更接近人类思维。 |
| ✅ 抽象能力强:支持函数、模块、对象等。 | |
| ✅ 开发效率高:少量代码即可实现复杂功能。 | |
| ✅ 易调试和维护:工具完善,结构清晰。 | |
| ✅ 可移植性强:通常可在不同平台运行。 | |
| 缺点 | ❌ 不能直接执行:需要编译器或解释器转换。 |
| ❌ 控制不够精细:难以直接操作底层硬件。 | |
| ❌ 存在额外开销:性能和资源占用可能较高。 | |
| ❌ 依赖运行环境:部分语言需要运行时或虚拟机。 |
- 目前普遍使用的
高级编程语言,有:C、C++、Java、Python、C#、JavaScript、Go 等。
提醒

1.6 编译型语言 VS 解释型语言
1.6.1 概述
- 高级编程语言出现之后,CPU 是不能直接理解的,还需要
翻译者,对应的典型方式有两种:
1.6.2 编译型语言 & 解释型语言
1.6.2.1 编译型语言
- 编译型语言的工作原理:在程序
运行之前,通过一个叫做编译器的工具,将源代码一次性全部翻译成目标机器能直接执行的机器码,如:qq.exe、wechat.exe 等。

- 编译型语言的执行过程:源代码(Hello.c)--> 编译器(GCC)--> 机器码(Hello.exe)--> CPU 直接运行。

- 编译型语言的典型代表语言:C、C++、Go、Rust、Swift 等。

- 编译型语言的优缺点,如下所示:
| 优缺点 | 描述 |
|---|---|
| 优点 | ✅️ 执行速度极快:因为程序运行时直接就是机器码,CPU 不需要再做任何翻译工作,性能最接近底层。 |
| ✅️ 不依赖运行环境:生成的可执行文件可以直接在目标机器上运行,不需要安装额外的语言环境。 | |
| 缺点 | ❌️ 跨平台性差:为 Windows (x86) 编译的程序,不能直接拿到 Mac (ARM) 上运行,即:换平台必须 重新编译。 |
| ❌️ 开发调试效率低:每次修改哪怕一行代码,都需要重新经历漫长的“编译”过程才能看到效果。 |
1.6.2.2 解释型语言
- 解释型语言的工作原理:在程序
运行时,通过一个叫做解释器的程序,逐行读取源代码,边翻译边执行,不生成独立的机器码文件。

- 解释型语言的执行过程:源代码(Hello.py)--> 解释器(Python)--> 边翻译边执行 --> CPU 直接运行。

- 解释型语言的典型代表语言:Python、JavaScript、Ruby、PHP、Bash 等。

- 解释型语言的优缺点,如下所示:
| 优缺点 | 描述 |
|---|---|
| 优点 | ✅️ 跨平台性极好:只要目标机器上安装了对应的解释器(如 Python 环境),同一份源代码就可以直接运行(“一次编写,到处运行”)。 |
| ✅️ 开发调试极快:改完代码直接运行,不需要等待编译,非常适合快速迭代和原型开发。 | |
| 缺点 | ❌️ 执行速度慢:因为每次运行都要“现场翻译”,比直接执行机器码慢得多(通常比编译型慢几倍到几十倍)。 |
| ❌️ 依赖运行环境:必须要求用户的电脑上安装了解释器,否则代码无法运行。 | |
| ❌️ 源码暴露:因为分发的是源代码,别人很容易看到你的核心逻辑(缺乏保密性)。 |
1.6.3 对比&总结
- 编译型语言 VS 解释型语言,如下所示:
| 维度 | 编译型语言 (C/C++) | 解释型语言 (Python/JS) |
|---|---|---|
| 翻译时机 | ⏱️ 运行前,一次性翻译完 | 🔄 运行时,逐行翻译 |
| 产物 | 📦 生成独立的机器码文件 ( .exe ) | 📤 不生成独立文件,直接输出结果 |
| 执行速度 | 🚀 极快(直接跑机器码) | 🐢 较慢(边翻译边执行) |
| 跨平台性 | ❌ 差(需针对不同平台重新编译) | ✅ 好(只要有解释器就能跑) |
| 开发效率 | ⚠️ 较低(修改后需重新编译) | 🚀 高(改完即跑) |
| 源码保密 | ✅ 高(别人只能看到机器码) | ❌ 低(直接分发源代码) |
1.6.4 现代视角的补充:界限正在模糊
- 随着技术发展,纯粹的
编译或解释已经不能完美满足需求,于是诞生了混合型:
点我查看 具体细节
| 混合型(中间态) | 描述 |
|---|---|
| 字节码 + 虚拟机(Java, C#) | 🔄 过程:Java 源代码先被编译成一种中间状态叫 “字节码”( .class 文件),然后由 Java 虚拟机(JVM)去解释执行或编译执行。 |
| ✨ 优势:完美结合了两者的优点。字节码是跨平台的,只要装了 JVM 就能跑(跨平台);JVM 内部又做了优化,速度比纯解释快。 | |
| JIT 即时编译 (现代 JavaScript, Python) | ⚡ 过程:解释器在运行时,如果发现某段代码被 频繁执行(热点代码),就会在内存中 临时把它编译成机器码 缓存起来,下次直接跑机器码。 |
| 🚀 优势:既保留了开发时的灵活性,又大幅提升了运行时的速度。 |

1.6.5 建议
- 如果追求
极致性能(游戏引擎、操作系统、高频交易),选编译型,如:C/C++、Rust。 - 如果追求
开发效率(数据分析、网站后端、AI),选解释型,如:Python、JS。 - 如果要做
大型企业级跨平台应用(微服务、大数据、中间件),选混合型,如:Java、C#。
第二章:初识 C 语言
2.1 C 语言的历史和辉煌
2.2 C 语言的标准
第三章:C 语言环境的搭建(🎯)
txt
MSYS2 MSYS
Unix 工具
平时不用单独开
MSYS2 UCRT64
GCC 环境
保留做 GCC 对照
MSYS2 CLANG64 ← 你现在主要使用
Clang + Meson + ASan/UBSan
MSYS2 MINGW64
传统环境
新项目基本不用
MSYS2 CLANGARM64
ARM64 Windows 才用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- CLion 的虚拟机配置:
txt
-Xmx2048m
-Dfile.encoding=UTF-8
-Dconsole.encoding=UTF-81
2
3
2
3
3.2 vscode
- 在 WSL2 中的 AlmaLinux-9 安装:
bash
# 更新系统
sudo dnf -y update
# 安装基础 C/C++ 环境
sudo dnf group install "Development Tools" -y
sudo dnf install gcc \
gcc-c++ \
gdb \
make \
cmake \
ninja-build \
pkgconf-pkg-config \
binutils \
git \
glibc-devel \
dnf-plugins-core -y
# 安装 glibc 调试信息工具
sudo dnf debuginfo-install glibc -y
sudo dnf install dnf-plugins-core -y
sudo dnf install glibc-debugsource -y
# 安装 clangd
sudo dnf install clang \
clang-tools-extra \
llvm \
lldb -y1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bash
# 查询 glibc
rpm -q glibc
rpm -q glibc-devel
rpm -q glibc-debuginfo
rpm -q glibc-debugsource
# 验证 GCC / GDB
gcc --version
gdb --version
# 验证 Clang 工具
clang --version
clangd --version
clang-format --version
clang-tidy --version
# 查询 glibc 源码
find /usr/src/debug -name 'vfprintf-internal.c' 2>/dev/null
find /usr/src/debug -name 'filedoalloc.c' 2>/dev/null1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- 在 WSL2 中的 Ubuntu 24.04 安装:
bash
# 更新系统
sudo apt update && sudo apt upgrade -y
# 启用 Universe
sudo apt install -y software-properties-common
sudo add-apt-repository -y universe
sudo apt update
# C / C++ 基础开发环境
sudo apt install -y \
build-essential \
gcc \
g++ \
gdb \
make \
cmake \
ninja-build \
pkg-config \
binutils \
git
# glibc 调试符号 + glibc 源码
sudo apt install -y \
libc6-dev \
libc6-dbg \
glibc-source \
xz-utils
# LLVM / Clang 工具链
sudo apt install -y \
clang \
clangd \
clang-tools \
llvm \
lldb
# --------------------------------------
# 自动找到 glibc 源码压缩包并解压
# --------------------------------------
GLIBC_ARCHIVE="$(find /usr/src/glibc \
-maxdepth 1 \
-type f \
-name 'glibc-*.tar.xz' \
| sort -V \
| tail -n 1)"
GLIBC_DIR="/usr/src/glibc/$(basename "$GLIBC_ARCHIVE" .tar.xz)"
if [ ! -d "$GLIBC_DIR" ]; then
sudo tar -xf "$GLIBC_ARCHIVE" -C /usr/src/glibc
fi
echo "glibc 源码目录:$GLIBC_DIR"
# --------------------------------------
# 全局配置 GDB 自动寻找 glibc 源码
# --------------------------------------
GLIBC_DIR="$(find /usr/src/glibc \
-maxdepth 1 \
-type d \
-name 'glibc-*' \
| sort -V \
| tail -n 1)"
touch "$HOME/.gdbinit"
sed -i \
'/# BEGIN UBUNTU GLIBC DEBUG/,/# END UBUNTU GLIBC DEBUG/d' \
"$HOME/.gdbinit"
cat >> "$HOME/.gdbinit" <<EOF
# BEGIN UBUNTU GLIBC DEBUG
directory $GLIBC_DIR
set debuginfod enabled on
# END UBUNTU GLIBC DEBUG
EOF
cat "$HOME/.gdbinit"
# --------------------------------------
# clangd 压制 glibc source 警告
# --------------------------------------
mkdir -p "$HOME/.config/clangd"
cat > "$HOME/.config/clangd/config.yaml" <<'EOF'
If:
PathMatch: /usr/src/glibc/.*
Diagnostics:
Suppress: '*'
EOF
cat "$HOME/.config/clangd/config.yaml"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
bash
# 检查所有开发工具路径
printf '%-10s %s\n' \
"gcc:" "$(command -v gcc)" \
"g++:" "$(command -v g++)" \
"gdb:" "$(command -v gdb)" \
"clang:" "$(command -v clang)" \
"clangd:" "$(command -v clangd)" \
"lldb:" "$(command -v lldb)"
# 检查所有版本
gcc --version | head -n 1
g++ --version | head -n 1
gdb --version | head -n 1
clang --version | head -n 1
clangd --version | head -n 1
lldb --version | head -n 1
ldd --version | head -n 1
# 检查 glibc 相关软件包
dpkg -l \
libc6 \
libc6-dev \
libc6-dbg \
glibc-source
# 检查 GDB 是否加载了 glibc 源码目录
gdb -q -nx \
-ex "source $HOME/.gdbinit" \
-ex "show directories" \
-ex "show debuginfod enabled" \
-ex "quit"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- vscode 插件:
bash
C/C++ Extension Pack # 配置 gcc 和 gdb 的路径
C/C++ Runner # 生成配置我呢间
clangd # 发布者:LLVM
code --install-extension ms-vscode.cpptools-extension-pack
code --install-extension franneck94.c-cpp-runner
code --install-extension llvm-vs-code-extensions.vscode-clangd
建议同时把微软 C/C++ 扩展的 IntelliSense 关闭,避免两个语言服务器同时分析:
{
"C_Cpp.intelliSenseEngine": "disabled"
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14