第四章 POD 类型与结构
C++ 与 C
本章标题叫做“POD类型与结构”,其中 POD 的含义是 Plain Old Data,中文译作“简旧数据”。正如字面意思,本章的内容将是有关一些简单、老旧的数据类型和数据结构。简单这个词姑且还好理解,“老旧”是从何而得呢?这就不得不稍微谈一点 C++ 的历史了。
在 20 世纪 70 年代初,美国贝尔实验室开发出一个名叫 UNIX 的操作系统。(这个操作系统在计算机历史上具有很重要的地位。)当时,这个操作系统是用一种被称为 B 的语言(如果再向前追溯,它的祖先是 BCPL、CPL 和 ALGOL 60 语言,不过它们都不太适合编写系统程序)。然而这种 B 语言过于接近硬件,而且扩展能力比较差。下面是一段 B 语言程序:
/* Hello World in B */
main() {
extern a, b, c;
putchar (a); putchar (b); putchar (c); putchar ('!*n');
}
a 'hell' ;
b 'o, w' ;
c 'orld' ;
在 B 语言中没有类型系统,而且只适用于特定机器硬件,开发起来难度还是很大。因此贝尔实验室的一位科学家丹尼斯·里奇(Dennis Ritchie)在其基础上研发了 C 语言。C 语言保留了 B 语言强大的硬件操控能力,并增添了类型系统和高效的可移植能力。下面是当时早期 C 语言的代码:
/* Hello World in C, K&R-style */
main() {
puts("Hello World!");
return 0;
}
里奇用 C 语言重新编写了 UNIX 系统。随后,软件工程师林奈斯·托瓦兹(Linus B. Torvalds)模仿 UNIX ,用 C 语言编写了目前最通用的操作系统内核 Linux。从此 C 语言开始发扬光大,称为目前最流行的编程语言之一。
20 世纪 70 年代中期,面向对象编程这一编程范式开始流行。教授本贾尼·斯特劳斯特卢普(Bjarne Stroustrup)于 1979 年进入贝尔实验室,将 C 语言进行了适用于“面向对象”的改良,称这种改良的语言为 C with Classes。
后来这门改良的编程语言改名为 C++,并吸收了大量的新特性(如虚函数、重载、多继承、静态、命名空间、异常处理、模板等,以及各种库)。与此同时,C 语言和 C++ 语言先后步入标准化,美国的标准委员会 ANSI 和国际标准组织 ISO 分别为这两种语言制定了统一的语言标准。(后来 ANSI C语言标准也收入 ISO。)这个时候,可以称 C++ 语言是 C 语言的超集,C 语言是 C++ 语言的子集:因为 C++ 不过是在 C 的基础上增加了诸多特性而已。下面是经过标准化后的 C 和 C++ 语言示例:
/* Hello World in C, Ansi-style */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("Hello World!");
return EXIT_SUCCESS;
}
// Hello World in ISO C++
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
}
不过事情在 90 年代发生了改观。由于 C 语言诞生之初就偏重于系统、硬件这些“底层”的服务,而 C++ 语言秉持着更易用、实用、通用的特性而偏向于高级编程,所以两者自然而然地发生了一定程度上的区分。1999 年,C 语言的新一代标准 C99 发布,加入了许多 C++ 未曾包含的特性(如复合字面量、VLA 等)。2011 年,C++11 和 C11 相继发布,这时 C 语言和 C++ 语言已经有了非常大的差别了。
话是这样说,但是两者毕竟同根同源,仍然存在大量的代码可以不经改动地从 C 迁移到 C++,或者反过来。因此那些可以直接从 C++ 迁移到 C 的代码,也就是兼容 C 的代码,可以称之为“老旧的”代码;而兼容 C 的数据类型,则被称为简单、老旧的数据类型,也就是 POD 类型了。只用 POD 类型实现的数据存储方式,我们姑且称它为 POD 结构吧。
大部分基础类型是 POD 类型:如 int
、long
和 double
,由 POD 类型构成的数组也是 POD 类型。接下来,我们先从数组开始讲解。
B 语言和 C 语言的命名其实都来自于人名,字母的排序只是巧合。C++ 的命名就是取自增运算符的含义。
其实 C99 以前 C 语言也不完全是 C++ 的子集,仍有一些细微的不兼容之处。
POD 类型曾经是一种类似具名要求(Named requirement)的规范,但在后来的标准中被标准布局类型这一术语替代。不过 POD 类型仍然客观存在,只是标准中不再提及。