C语言:半个世纪依然站在底层开发的中心

它没有虚拟机,没有运行时,却驱动着整个世界

如果你拆开一台智能汽车、一个路由器、甚至一颗卫星,里面大概率运行着用 C 语言写成的程序。这门诞生于贝尔实验室的语言,半个多世纪以来,始终没有离开过底层开发的核心位置。

一.故事的开端:BCPL → B → C

上世纪 70 年代初,贝尔实验室里,Ken Thompson 和 Dennis Ritchie 正面临一个问题:当时的操作系统大多用汇编写的,太难移植。

Thompson 之前搞出了一门叫 B 的语言,它又源于更早的 BCPL。Ritchie 在此基础上重新设计,增加了类型系统、改进了编译器——结果就是 C 语言

这个名字很直接:B 后面就是 C。

更重要的是,Thompson 和 Ritchie 随后用 C 完全重写了 UNIX 操作系统。这在当时是一个极其大胆的决定——用高级语言写操作系统?大家不信。但他们做到了,也由此证明了:C 能写出与汇编一样快的系统软件。

UNIX 成就了 C,C 也成就了 UNIX。

C 语言并未停步,而是继续演进。从 K&R C、C89、C99、C11、C17,一直走到 C23——2023 年发布的最新标准。

二.C 到底特别在哪里?

如果你只用一个句子记住 C 语言,可以是:

一门能让你写出与汇编一样高效的代码、却几乎不依赖任何运行环境的程序设计语言。

更具体地说,C 被设计成这样:

  • 编译起来不复杂

  • 直接操作内存(低级存储器)

  • 最终生成的机器码很少

  • 不需要虚拟机 / 解释器 / 任何运行时环境,就能跑在硬件上

这在今天依然是一种非常稀缺的能力。

三、为什么底层开发离不开 C?

C 语言最主场的舞台,就是底层开发。原因有四:

1. 对内存的绝对控制

指针就是内存地址。你可以精确地分配、读写、释放每一个字节。高级语言通常不让你这么干,但底层系统经常必须这么干。

2. 极小的运行时开销

没有垃圾回收,没有异常处理栈的额外负担。你写什么,机器就大致执行什么。

3. 硬件直接操作

读写寄存器、操作 I/O 端口、处理中断——这些在 C 里是日常操作。

4. 跨平台的本质

虽然能直接操作硬件,但如果你写的是标准 C 代码(不掺杂内联汇编或特定硬件地址),它可以在各种平台上重新编译后运行。

这里有个常见误区:C 的跨平台不是“二进制直接跑”,而是“源码级可移植”。

一个好的 C 程序,可以在嵌入式 ARM 芯片和超级计算机节点上用同一份源代码分别编译运行。

四、哪些地方在用 C?(比你想象的多得多)

领域典型例子
操作系统内核Linux、Windows 内核、FreeBSD、各种 RTOS
嵌入式系统单片机程序、汽车 ECU、智能家电控制器
数据库MySQL、PostgreSQL、SQLite
编程语言实现CPython、Lua、PHP 内核、Ruby 底层
驱动与固件设备驱动、硬盘固件、网卡固件
高性能计算超算底层数值库、通信中间件

你会发现一个有趣现象:很多“其他语言”本身,就是用 C 实现的。

五、C 的对比优势(一图看懂)

能力C汇编Java/C#Python
直接操作硬件✔ 强✔✔ 最强
源码级跨平台✔ 高✔(二进制)✔(解释)
是否需要运行时✘ 不需要✘ 不需要✔ 需要✔ 需要
适合裸机/单片机
开发效率中等很低很高

C 打的是一个“平衡牌”:我让你写系统软件,同时不让你痛苦像写汇编那样。

六、一个例子说明“跨平台到极端”

下面这段代码,一字不改,可以编译并运行在:

  • 一颗几块钱的 ARM Cortex-M 单片机(无操作系统)

  • 你手边的 Windows / Linux PC

  • 一台拥有数千个核心的超级计算机节点

#include <stdio.h>

int main() {
    printf("C: 从嵌入式到超算,一套代码。\n");
    return 0;
}

这不是什么魔法,而是 C 语言经过数十年标准化和广泛移植的结果。

七、结语:你未必天天写 C,但很难绕过它

现代软件工程中,你完全可能一辈子不写 C 代码。但只要你深入一点——比如调一个性能瓶颈、改一个数据库配置项、理解操作系统行为——你会发现,那些最终决定“机器到底做了什么”的地方,往往还是 C。

C 不是给所有人准备的日常语言,但它是整个计算机世界的地基语言。

学会 C 不是因为你要用它写一切,而是因为它能告诉你:计算机究竟是怎样执行你的每一行代码的。

你对 C 语言感兴趣,是因为嵌入式、操作系统,还是单纯想弄清楚指针和内存?欢迎聊聊你的方向。