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

问题描述 投票:38回答:11

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

它在编程和逻辑中是如此常见,我不明白缺少明确的类型和符号。

c language-design c99 c89
11个回答
25
投票

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

PDP-11的出现揭示了B语义模型的几个不足之处。首先,它的角色处理机制,继承了BCPL的一些变化,是笨拙的:使用库程序将打包的字符串传播到单个单元格然后重新打包,或访问和替换单个字符,开始感到尴尬,甚至愚蠢,面向字节的机器。

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

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

(强调我的。)

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


1
投票

因为他们没有把它放入。抱歉,如果这听起来有点嗤之以鼻,但基本上没有这样定义。

记住大多数人#define TRUE和FALSE。

你可以说bool是标准的 - 但显然它在C99之前不是标准 - 这是10年前制造的;)他们添加它然后它显然是一个缺失的项目。


0
投票

因为没有人可以预见一切,包括编程语言中缺少数据类型。


17
投票

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

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


11
投票

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

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

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


10
投票

CPU没有“布尔类型”,它们只处理字节和它们的倍数,因此当时布尔类型没有任何意义,因为它没有给出优势(为什么在只能检查“是0”时使用类型或“不是空”)


7
投票

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


6
投票

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

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

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


5
投票

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

  • 位寻址处理器并不常见(现在仍然没有),因此编译器实际上无法使用“真正的布尔”类型来保存任何空间 - 布尔值仍然至少与无论如何,一个char(如果你希望有效地访问它)。
  • 类型比int窄的类型在表达式中扩展到int - 所以布尔运算符仍然适用于int操作数。

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

请记住,C语言确实有一组生成布尔结果的运算符(定义为0或1) - !&&||!===<<=>>= - 所以它只是一个专用的布尔类型那不存在。


4
投票

历史原因,可能是:

受ALGOL影响很大的CPL很可能有一个布尔类型,但我的google-fu不足以找到这方面的参考。但CPL过于雄心勃勃,导致了一个名为BCPL的精简版本,它的好处是你可以在可用的硬件上实现它。

BCPL只有一个类型 - 'word' - 如果0在布尔上下文中被解释为false,如果~0被解释为true(0的补码,如果被解释为有符号二进制补码整数则表示值-1)。任何其他价值的解释都取决于实施。

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


2
投票

添加一个与整数不兼容的单独“布尔”类型会使编译器比仅仅为此目的使用整数更复杂。具有与整数兼容的单独布尔类型使得必须指定将除0或1之外的值存储到布尔对象中的可能后果,或者对布尔对象执行数值计算,该布尔对象的表示既不包含与“ 0“也不是”1“。鉴于:

someBool = intFunction();
someInt = someBool;

要求someInt必须接收值1,如果intFunction返回任何非零值通常会使上面的代价更高

someChar = intFunction();
someInt = someChar;

在需要前一种语义的情况下,可以在不使用布尔类型的情况下实现它们,通过:

someChar = !!intFunction();
someInt = someChar;

因为任何可以使用布尔类型完成的事情也可以在没有它们的情况下完成,并且在许多情况下使用字符类型的代码比布尔类型更有效,我建议从来没有(现在仍然没有)任何真实的需要他们。

© www.soinside.com 2019 - 2024. All rights reserved.