Hotdry.

Article

从BCPL到ANSI C:花括号语法的演进与影响

追溯Unix V6到C语言标准化历程中花括号语法的演进脉络,解析这一语法设计对现代编程语言体系的深远影响。

2026-05-24programming-languages

花括号 {} 是现代编程语言中最具辨识度的语法符号之一。从 C、C++ 到 Java、JavaScript,这一看似简单的符号承载着半个多世纪的编程语言演进史。追溯其源头,我们需要回到 1960 年代的系统编程语言探索,理解从 BCPL 到 B 再到 C 的语法传承脉络。

BCPL:花括号语法的源头

花括号作为块界定符的设计最早可追溯至 BCPL(Basic Combined Programming Language)。Martin Richards 于 1960 年代中期在 MIT 设计这门语言时,引入了一套简洁而优雅的语法体系。BCPL 采用 let...be 结构声明过程,并使用花括号明确界定代码块的作用域范围。这种设计选择并非偶然 —— 它反映了早期系统编程语言对「清晰界定复合语句」这一需求的回应。

BCPL 的一个显著特点是其 ** 无类型(typeless)** 设计:所有数据都被视为固定长度的「字(word)」或「单元(cell)」。程序通过操作这些基本单元来完成计算,而花括号则负责界定这些操作的边界。这种语法风格在当时的系统编程领域颇具影响力,为后来 Unix 系统的开发奠定了语言基础。

B 语言:内存限制下的传承

1969 年,Ken Thompson 在 PDP-7 上开发 Unix 时面临严峻的内存限制 —— 仅有 8K 字(18 位)的内存空间。他需要一个比汇编更高级、但又足够轻量的系统编程语言。Thompson 选择基于 BCPL 创建 B 语言,将其「压缩」进极小的内存 footprint 中。

B 语言继承了 BCPL 的核心语法特征,包括花括号作为块界定符。正如 Dennis Ritchie 在《The Development of the C Language》中所述:「B 可以被视为没有类型的 C;更准确地说,它是被压缩进 8K 字节内存并经过 Thompson 大脑过滤的 BCPL。」在这一传承过程中,花括号语法得以保留,成为 B 语言中界定复合语句和控制流结构的标准方式。

值得注意的是,B 语言在某些语法细节上做出了调整。例如,B 使用 /* */ 包围注释(受 PL/I 影响),而 BCPL 使用 // 忽略行尾内容;B 使用单字符 = 表示赋值,而非 BCPL 的 :=。然而,花括号作为块界定符的核心设计始终未变

从 NB 到 C:类型系统的引入

1971 年,PDP-11 的引入暴露了 B 语言的局限性。这台 16 位字节寻址机器与此前字寻址的硬件架构存在本质差异,B 语言的无类型模型难以高效处理字符和字节寻址。Dennis Ritchie 开始扩展 B 语言,首先引入了 charint 类型,创建了短暂的 NB("New B")语言。

这一类型系统的引入对花括号语法产生了深远影响。在 NB 中,花括号不仅界定代码块,还需要与新的类型声明语法协同工作。Ritchie 设计了「声明语法模仿表达式语法」的原则 —— 这一 C 语言最具特色的设计决策之一。例如:

int i, *pi, **ppi;

声明中的 *pi**ppi 反映了表达式中解引用的语法结构。花括号在这一体系中承担着界定复合类型(如结构体)和代码块的双重职责。

1972 年,语言正式命名为 C。此时的 C 已经具备了现代 C 语言的核心特征:类型系统、结构体、指针运算,以及 ——花括号界定的块结构

Unix V6:花括号语法的成熟

1975 年发布的 Unix Version 6 标志着 C 语言和花括号语法的重要里程碑。这是第一个广泛传播的 Unix 版本,也是 C 语言作为系统编程语言成熟的见证。

Unix V6 的源代码展现了花括号语法在大型系统项目中的应用模式。内核代码中,花括号清晰地界定着函数体、条件分支、循环体和复合语句。这种语法设计带来了几个关键优势:

  1. 作用域明确性:花括号创建的词法作用域使变量生命周期一目了然
  2. 代码结构化:块结构支持嵌套,使复杂控制流得以清晰表达
  3. 编译器简化:块界定符使单遍编译器能够高效生成代码

Unix V6 的成功使 C 语言和花括号语法成为系统编程的事实标准。这一时期形成的编码风格 —— 包括花括号的位置约定(K&R 风格 vs Allman 风格)—— 至今仍在影响代码规范。

ANSI C 标准化:语法的固化

到了 1980 年代初,C 语言的广泛应用催生了标准化的需求。1983 年,ANSI 成立 X3J11 委员会;1989 年,**ANSI C 标准(C89)** 正式发布,随后被 ISO 采纳为 ISO/IEC 9899:1990。

标准化过程对花括号语法进行了谨慎的确认和微调。委员会采纳了函数原型语法,使参数类型成为函数签名的一部分:

double sin(double);  /* ANSI C 风格 */

花括号在这一新标准中继续承担着块界定和初始化列表的双重角色。标准还明确了复合语句(compound statement)的语法定义,固化了花括号在 ifwhilefor 等控制结构中的使用方式。

对现代编程语言的影响

C 语言的花括号语法通过多种途径影响了后续编程语言的设计:

C++ 直接继承了 C 的语法基础,并扩展了花括号的使用场景 —— 从构造函数初始化列表到 lambda 表达式捕获列表。C++11 引入的统一初始化语法(uniform initialization)进一步拓展了花括号的语义。

JavaC# 在语法层面大量借鉴 C 风格,花括号成为类、方法、控制结构的标配界定符。这种设计选择使 C 程序员能够快速迁移到这些新语言。

JavaScript 虽然语法源自 Scheme/Self 传统,但在语句层面采用了 C 风格的花括号块结构。ES6 引入的块级作用域(let/const)进一步强化了花括号在作用域管理中的重要性。

Go 语言的设计者(包括 Ken Thompson 本人)在设计中保留了花括号,但去除了分号作为语句结束符的要求,体现了对 C 语法传统的继承与革新。

局限与反思

花括号语法并非没有争议。对初学者而言,花括号的位置风格(K&R vs Allman)曾是代码审查的争议点;括号匹配错误也是常见的语法 bug 来源。Python 等语言采用的缩进块结构提供了另一种代码组织思路。

然而,花括号语法的显式性工具友好性使其在编译器实现、代码格式化工具和静态分析工具方面具有优势。现代 IDE 的自动括号匹配和折叠功能,进一步降低了使用门槛。

结语

从 BCPL 的实验性设计到 ANSI C 的标准化固化,花括号语法经历了二十余年的演进历程。这一看似简单的语法符号,承载着系统编程语言对「清晰界定代码边界」这一基本需求的持续探索。理解这一演进脉络,有助于我们更深入地把握 C 语言的设计哲学,以及现代编程语言语法的传承与变革。


资料来源

  • Dennis M. Ritchie, "The Development of the C Language," History of Programming Languages-II, ACM Press, 1996
  • Martin Richards, "The BCPL Reference Manual," MIT Project MAC Memorandum M-352, July 1967

programming-languages

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com