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

时间:2010-03-11 15:03:52

标签: c language-design c99 c89

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

这在编程和逻辑中是如此常见,我不明白显式类型和符号的缺失。

11 个答案:

答案 0 :(得分: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 :(得分:17)

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

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

答案 2 :(得分:10)

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

答案 3 :(得分:10)

通常(在某些情况下仍然)将零视为false,将任何非零视为true。这有利于速记:例如,您可以使用while (remaining != 0)代替while (remaining)

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

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

答案 4 :(得分:7)

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

答案 5 :(得分:6)

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

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

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

答案 6 :(得分:5)

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

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

  • 无论如何,比int更窄的类型在表达式中被扩展为int - 因此布尔运算符仍可用于int个操作数。

..所以看起来似乎没有足够令人信服的案例,专用的布尔类型实际上会传达实际的好处。

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

答案 7 :(得分:4)

历史原因,可能是:

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

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

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

答案 8 :(得分:2)

添加单独的&#34;布尔&#34;与整数不兼容的类型会使编译器比仅仅为此目的使用整数更复杂。具有与整数兼容的单独布尔类型使得必须指定存储0以外的值的可能后果 或1或布尔对象,或对布尔值执行数值计算 对象,其表示既不包含与之关联的位模式 &#34; 0&#34;也不是&#34; 1&#34;。给出:

someBool = intFunction();
someInt = someBool;

如果intFunction返回任何非零值,则要求someInt必须接收值1通常会使上面的内容比

更贵
someChar = intFunction();
someInt = someChar;

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

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

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

答案 9 :(得分:1)

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

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

你可能会说bool是标准的 - 但很明显它在C99之前不是标准 - 这是10年前制作的;)他们在它显然是一个缺失的项目时添加它。

答案 10 :(得分:0)

因为没有人可以预见到包括编程语言中缺少数据类型在内的所有内容。