C 旨在使编写编译器变得容易。它基于这一原则做了很多事情。指针的存在只是为了使编写编译器更容易,头文件也是如此。继承到 C++ 的许多东西都是基于与这些特性的兼容性,这些特性使编译器编写更容易。
其实这是个好主意。在创建 C 时,C 和 Unix 是一对。 C 移植 Unix,Unix 运行 C。这样,C 和 Unix 可以迅速从一个平台传播到另一个平台,而基于汇编的操作系统必须完全重写才能移植。
在一个文件中指定接口并在另一个文件中实现的概念一点也不坏,但这不是 C 头文件的含义。它们只是一种限制编译器必须通过您的源代码进行的传递次数的方法,并允许对文件之间的契约进行一些有限的抽象,以便它们可以通信。
这些项目、指针、头文件等...与其他系统相比并没有真正提供任何优势。通过在编译器上投入更多精力,您可以像编译指向完全相同的对象代码的指针一样轻松地编译引用对象。这就是 C++ 现在所做的。
C 是一种伟大而简单的语言。它的功能集非常有限,您可以轻松编写编译器。移植它通常是微不足道的!我并不是想说它是一种糟糕的语言或任何东西,只是 C 在创建它时的主要目标可能会在语言中留下一些现在或多或少不必要的残余物,但为了兼容性将保留下来。
似乎有些人并不真正相信 C 是为移植 Unix 而编写的,所以在这里:(from)
UNIX 的第一个版本是编写的
用汇编语言,但 Thompson 的
目的是写成
使用高级语言。
Thompson 于 1971 年首次尝试使用
PDP-7 上的 Fortran,但放弃了
第一天之后。然后他写了一个
他称之为B的非常简单的语言,
他开始使用 PDP-7。它
工作,但有问题。
首先,因为实施是
解释,它总是
慢。二、B的基本概念,
这是基于面向单词的
BCPL,只是不适合
像新的面向字节的机器
PDP-11。
Ritchie 使用 PDP-11 添加类型
到B,有一段时间被称为NB
为“新B”,然后他开始
为它写一个编译器。 “所以这样
C的第一阶段真的是这两个
连续的几个阶段,首先,
一些语言从 B 改变,真的,
添加类型结构
语法上有很大的变化;和做
编译器,”Ritchie 说。
“第二阶段比较慢,”他说
用 C. Thompson 重写 UNIX
开始于 1972 年夏天,但
两个问题:弄清楚如何运行
基本的协程,也就是如何
将控制从一个进程切换到
其他;以及获取难度
正确的数据结构,因为
原版C没有
结构。
"造成的事物的组合
肯放弃整个夏天,”
里奇说。 “一年来,我补充说
结构,并可能使
编译器代码稍微好一些——
更好的代码——等等
夏天,那是我们制作
齐心协力,实际上做了重做
C语言的整个操作系统。”
这是我的意思的一个完美例子。来自 cmets:
指针的存在只是为了让编写编译器更容易?不,指针的存在是因为它们是对间接概念的最简单的抽象。 ——亚当·罗森菲尔德(一小时前)
你是对的。为了实现间接,指针是实现的最简单的抽象。它们绝不是最容易理解或使用的。数组要容易得多。
问题?要像指针一样高效地实现数组,您几乎必须在编译器中添加大量代码。
没有理由他们不能设计没有指针的 C,而是使用如下代码:
int i=0;
while(src[++i])
dest[i]=src[i];
需要付出很多努力(在编译器部分)才能排除显式 i+src 和 i+dest 添加并使其创建与此相同的代码:
while(*(dest++) = *(src++))
;
事后分解变量“i”是困难的。新的编译器可以做到这一点,但在当时是不可能的,而且在糟糕的硬件上运行的操作系统几乎不需要像这样的优化。
现在很少有系统需要这种优化(我在最慢的平台之一上工作——有线电视机顶盒,我们的大部分东西都是用 Java 编写的),在极少数情况下你可能需要它,新的 C 编译器应该足够聪明,可以自行进行这种转换。