为什么 C 在 C99 之前没有布尔数据类型?
-
19-09-2019 - |
题
我意识到你可以 #define
一些整数,但为什么 C 在 C99 之前没有专用的布尔数据类型?
这在编程和逻辑中很常见,我不明白缺乏显式类型和符号。
解决方案
如果您在图书馆花一点时间,你不必去揣测。 下面是从丹尼斯里奇的文件采取基于C 演变的一些声明。上下文是丹尼斯是建立在肯·汤普森的B语言,这是在非常小的PDP-7,按字寻址机实施。由于不断增长的兴趣,该集团拿到了第一个PDP-11的一个。丹尼斯写入,
的PDP-11的出现暴露B的语义模型的几个不足之处。首先,它的字符处理机制,继承了从BCPL一些变化,是笨拙:使用库程序传播打包字符串成单个细胞,然后重新包装,或访问并替换个别字符,开始觉得别扭,甚至是愚蠢的,在面向字节的机器。
在具有指针处理的B和BCPL模型隐含开销:语言规则,通过在字的阵列限定的指针作为指标,强迫指针被表示为字索引。每个指针引用产生从指针到由硬件所期望的字节地址一个运行时标转换。
由于所有这些原因,似乎由于打字方案是必要的,以应付字符和字节寻址,并为即将到来的浮点硬件准备。其他问题,特别是类型的安全性和接口检查,似乎并不那么重要,因为他们后来成了。
(重点煤矿。)
本文接着描述丹尼斯的斗争,以创造新的指针语义,使阵列工作,来到这个新奇的想法struct
条款。类型安全的概念和区别布尔从整数似乎并不重要,直到很久以后: - )
其他提示
Ç实际上比一个更高级别的汇编语言更小。是的,它得到了控制结构和诸如此类的东西,它甚至有类型的汇编当然不需要。
但这种语言是几十年前设计的。而且,由于每一个布尔结果下到各个位处理器的状态字这显然足以只是用一个整体的数据类型吧。它由编译器可能有点不太复杂,因为你可以省略某些类型检查(在后来的语言控制结构的需要的一个布尔值,在C他们只需要0或别的整数值)
这是常见的(现在仍然是在某些情况下)来治疗零假和任何非零为真。这具有的优点为简写:例如,代替while (remaining != 0)
的您也可以只使用while (remaining)
某些语言标准化了真正存在-1。这样做的原因是,在二进制补码表示法(其中大部分计算机使用来表示负数)时,按位不为0是-1(在8位二进制,11111111
是十进制-1)。
随着时间的推移,人们认识到使用编译器定义的常数将防止许多潜在的混乱。它已经有一段时间,因为我已经做了C ++,但我确信任何非零值仍然会评估“真”。
一个CPU没有“布尔型”,他们只在字节,并将它们的倍数工作,所以一个boolean类型当时没有任何意义,因为它没有给出一个优势(为什么要使用一个类型时,你只能检查“是0" 或 “不为空”)
我怀疑它被认为是足够了的整数类型,0是虚假和任何不为0真。
用来保存一个布尔值(通常)的类型体现空间和时间之间的权衡。您可以通过使用一个int(通常为四个字节)通常获得的(至少对于单个操作)最快的结果。在另一方面,如果你使用非常多,它可以使很多更有意义使用一个字节甚至收拾他们所以每次你存储用途值只有一个位 - 但是当/如果你这样做,读取或写入的单个位变得基本上更昂贵(并使用额外的代码)。
由于没有一个答案,这是真的“正确的”,他们离开的决定,用户根据他们写程序的要求做出。
真正的问题,那么,就是为什么一个布尔类型是C99加入。我的猜测是,一对夫妇的因素参与。首先,他们意识到,可读性和方便程序员现在通常不如授人以绝对最佳的性能更重要。其次,编译器现在要做相当多的全球分析,所以它至少可以猜测,有人的可能的写,试图选择一个表示这是最适合某个特定的程序(虽然我不编译知道的任何确实)。
旧 C 并不是真正“缺少”布尔类型 - 只是所有整型类型也被认为适合执行双重任务,即存储布尔值。我认为有两个主要原因:
位寻址处理器根本不常见(现在仍然不常见),因此编译器实际上无法使用“真正的布尔”类型来节省任何空间 - 布尔值仍然至少与A
char
无论如何(如果您希望有效地访问它)。类型窄于
int
被扩大到int
无论如何,在表达式中 - 所以布尔运算符仍然可以工作int
操作数。
..所以看起来没有足够令人信服的案例来证明专用的布尔类型实际上可以带来实际的好处。
请记住,C 语言确实有一组产生布尔结果的运算符(定义为 0 或 1) - !
, &&
, ||
, !=
, ==
, <
, <=
, >
和 >=
- 所以它只是一个不存在的专用布尔类型。
历史的原因,可能是:
CPL,这是深受ALGOL的影响,很可能有一个布尔类型,但我的谷歌福并不足以找到这个参考。但是CPL是为它的时间过于雄心勃勃,造成所谓的BCPL的精简版本,其中有,你可以真正实现它可用的硬件优势。
BCPL只有单一类型 - 的“单词” - 这是在布尔值的上下文解释为假,如果0
并作为真如果~0
(意味着0
的补码,如果解释为签署其将代表值-1
二进制补码整数)。任何其他值的解释是依赖于实现的。
静止无类型后继B之后,C再引入一个类型的系统,但它仍然严重地受到其前辈的无类型性质的影响。
添加一个单独的“布尔”类型,是不兼容的整数会作出编译器不是简单地使用整数为目的更加复杂。具有单独的布尔类型,是与整数兼容使得有必要指定存储除0以外的值的可能后果 或1到布尔对象,或在执行布尔数值计算 对象,其表示包含既不与相关联的位图案 “0”,也不是 “1”。给出:
someBool = intFunction();
someInt = someBool;
要求someInt必须接收值为1,如果intFunction返回任何非零值通常将使比
以上更昂贵someChar = intFunction();
someInt = someChar;
在的情况下,将需要前者语义,它们可以在不使用布尔类型的实现,通过:
someChar = !!intFunction();
someInt = someChar;
由于任何可以使用布尔类型来完成,也没有他们来完成,并且在使用的字符类型可以比布尔类型更高效的许多情况下的代码,我建议,从来没有(现在仍然是不)任何实际需要它们。
由于他们不把一个在抱歉如果这听起来snippish,但基本上没有这样定义
记住大多数人#定义TRUE和FALSE。
您可能会说布尔IS标准 - 但明显C99之前没有标准 - 这是10年前提出;)他们补充它,然后当它成为一个明显缺失项目
。由于没有可以预见的一切,包括在编程语言中缺少的数据类型。