为什么C在C99之前没有布尔数据类型?

xyz*_*xyz 40 c language-design c99 c89

我意识到你可以只是#define一些整数,但为什么C在C99之前没有专用的布尔数据类型?

它在编程和逻辑中是如此常见,我不理解显式类型和符号的缺失.

Nor*_*sey 25

如果你在图书馆花一点时间,你不必推测.以下是Dennis Ritchie关于C演变的论文中的一些陈述.上下文是Dennis正在建立Ken Thompson的语言B,这是在非常小的PDP-7上实现的,这是一台带字的机器.由于兴趣日益增长,该集团获得了最早的PDP-11之一.丹尼斯写道,

PDP-11的出现揭示了B语义模型的几个不足之处.首先,它的字符处理机制,继承了从BCPL一些变化,是笨拙:使用库程序传播打包字符串成单个细胞,然后重新包装,或访问并替换个别字符,开始觉得别扭,甚至是愚蠢的,在面向字节的机器.

B和BCPL模型在处理指针时隐含了开销:语言规则,通过将指针定义为单词数组中的索引,强制指针表示为单词索引.每个指针引用都生成从指针到硬件预期的字节地址的运行时标度转换.

由于所有这些原因,似乎需要一个打字方案来处理字符和字节寻址,并为即将到来的浮点硬件做准备.其他问题,特别是类型安全和界面检查,似乎并不像以后那么重要.

(强调我的.)

本文接着描述了Dennis努力发明一种新的指针语义,使数组工作,以及与这种新奇的struct想法达成协议.类型安全的概念和区分布尔与整数之间的关系在很久之后似乎并不重要:-)


Joe*_*oey 17

C实际上只是一种更高级的汇编语言.是的,它有控制结构和诸如此类,它甚至得到了汇编程序当然不需要的类型.

但这种语言是几十年前设计的.由于每个布尔结果都归结为处理器状态字中的各个位,因此显然只需使用整数数据类型即可.它使得编译器可能稍微复杂一点,因为你可以省略一些类型检查(在以后的语言中,控制结构需要一个布尔值,在C中它们只需要0或其他的整数值).

  • 请记住,早期的C也使用`char*`之前`void*`被标准化为通用指针类型.处理器没有"void"的概念,因此该语言使用硬件理解的最小分辨率数据指针.后来出现了更多像"void*"这样的"抽象"概念.C是一种非常接近金属的语言,并将真/假抽象为一种新的数据类型,它不能反映出硬件可以独特理解的东西没有多大意义("bool"只是一种` char`有额外的限制,如果你真的需要它,你自己很简单`typedef`). (11认同)

Dan*_*zey 11

在某些情况下(并且在某些情况下)将零视为假并且将任何非零视为真是常见的.这有利于速记:例如,而不是while (remaining != 0)你可以使用while (remaining).

有些语言标准化为真实-1.其原因在于二进制补码表示法(大多数计算机用来表示负数),0的按位 - 不是-1(8位二进制,11111111十进制-1).

随着时间的推移,人们意识到使用编译器定义的常量可以防止很多潜在的混淆.自从我完成C++以来已经有一段时间了,但我相当确定任何非零值仍将评估为"true".

  • 在比较运算符和布尔和/或/不运算符分别为真或假的值为1或0的意义上,正1**在C中是**"真".但是最好不要将true视为具有值,因为任何非零值都是真的. (4认同)
  • 当我第一次发现它时,我总是发现0/-1这个有趣的东西 - 特别是因为很多老师/讲师会错误地解释说积极的1是"真实的". (2认同)

Mor*_*dur 10

一个CPU没有"布尔型",他们只在字节,并将它们的倍数工作,所以一个boolean类型当时没有任何意义,因为它没有给出一个优势(为什么要使用一个类型时,你只能检查"0"或"不是空")

  • 当然CPU有布尔类型.标志寄存器塞满了它们! (2认同)
  • 是的,但它们不是通用的。 (2认同)

Vat*_*ine 7

我怀疑有一个整数类型被认为是足够的,0为假,任何不是0.


Jer*_*fin 6

用于存储布尔值(通常)的类型体现了空间和时间之间的权衡.通常使用int(通常为4个字节)可以获得最快的结果(至少对于单个操作而言).另一方面,如果你使用的很多,使用一个字节甚至打包它们会更有意义,因此你存储的每个值只使用一个位 - 但是当你这样做时,读取或写入单个位变得非常昂贵.

由于没有一个答案真的"正确",他们根据他们编写的程序的要求将决定留给用户.

那么,真正的问题是为什么在C99中添加了布尔类型.我的猜测是涉及到几个因素.首先,他们意识到程序员的便利性现在通常更重要,因为它可以提供绝对最佳的性能.其次,编译器现在做了更多的全局分析,所以至少可以猜测有人可能会编写一个编译器,试图选择一个最适合特定程序的表示(尽管我不知道任何真正的程序) ).


Chr*_*oph 5

历史原因,大概是:

CPL 深受 ALGOL 的影响,很可能有布尔类型,但我的 google-fu 不足以找到这方面的参考。但 CPL 对于当时来说过于雄心勃勃,因此产生了一个名为 BCPL 的精简版本,它的好处是您可以在可用的硬件上实际实现它。

BCPL 只有一种类型 - “单词” - 在布尔上下文中被解释为 false if0和 true if ~0(表示 的补码,如果解释为带符号的补码整数,则0表示该值)。-1任何其他值的解释取决于实现。

在仍然无类型的后继者 B 之后,C 重新引入了类型系统,但它仍然受到其前辈的无类型性质的严重影响。


caf*_*caf 5

旧C并没有真正"错过"一个布尔类型 - 只是所有的整体类型都被认为适合做双重任务,存储布尔值.我可以看到两个主要原因:

  • 位寻址处理器并不常见(现在仍然没有),因此编译器实际上无法使用"真正的布尔"类型来保存任何空间 - 布尔值仍然至少与一个char无论如何(如果你希望有效地访问它).

  • 更窄类型int加宽到int在表达无论如何-这样的布尔运算符将仍然在工作,int操作数.

..所以它看起来似乎没有足够引人注目的情况,专用的布尔类型实际上会传达实际的好处.

请记住,C语言确实有一组产生布尔结果运营商(定义为0或1) - ,!,&&,||,!=,==,,< 和-因此它只是一个专用的布尔类型这是不存在的.<=>>=