【问题标题】:Why _Bool and bool instead of int8_t or char?为什么使用 _Bool 和 bool 而不是 int8_t 或 char?
【发布时间】:2020-01-22 14:32:00
【问题描述】:

我想到了 C 中的 _Bool/ bool (stdbool.h) 和 C++ 中的 bool 的类型。


我们使用布尔类型来声明对象,这些对象只能保存 0 或 1 的值。 例如:

_Bool bin = 1;

bool bin = 1;

(注意:bool_Boolstdbool.h头文件中的宏。)

在 C 中,

bool bin = 1;

在 C++ 中。


但是_Boolbool 的布尔类型真的有效吗?


我做了一个测试,以确定每个对象在内存中的大小:

对于 C:

#include <stdio.h>
#include <stdbool.h>   // for "bool" macro.

int main()
{
    _Bool bin1 = 1;
    bool bin2 = 1; // just for the sake of completeness; bool is a macro for _Bool.    

    printf("the size of bin1 in bytes is: %lu \n",(sizeof(bin1)));
    printf("the size of bin2 in bytes is: %lu \n",(sizeof(bin2)));  

    return 0;
}

输出:

the size of bin1 in bytes is: 1
the size of bin2 in bytes is: 1

对于 C++:

#include <iostream>

int main()
{
    bool bin = 1;

    std::cout << "the size of bin in bytes is: " << sizeof(bin);

    return 0;
}

输出:

the size of bin in bytes is: 1 

因此,布尔类型的对象确实存储在内存中的 1 字节(8 位)内,而不仅仅是一个 1 位,因为它通常只需要。

这里讨论的原因是:Why is a char and a bool the same size in c++?。这不是我的问题。


我的问题是:

  • 为什么我们在 C 中使用 _Bool/ bool (stdbool.h) 和在 C++ 中使用 bool 类型,如果它们在内存中提供好处存储,因为它是专门假装使用这些类型的?

  • 为什么我不能只使用int8_tchar的类型(假设char在具体实现中包含8位(通常是这种情况))?

是否只是为了给代码读者提供一个明显的印象,即各个对象仅用于01/truefalse目的?

非常感谢您的参与。

【问题讨论】:

  • 嗯,根据个人经验,我曾经提出过一个测试用例,其中bool 的正确使用实际上比使用int 的对应物减少了代码大小。很遗憾记不起细节了。
  • 是否只是为了给代码读者提供一个明显的印象,即各个对象仅用于 0 或 1/true 或 false 目的? 那是一个主要好处。
  • 我确实使用bool 来使用truefalse 而不是 01。如果你认为10 很好,你就不需要bool
  • 不要忘记,由于booluint8_t 的不同类型,某些模板的行为可能会有所不同。 (是的,我看着你std::vector&lt;bool&gt;
  • @MartinMorterol 不要太难看。当你这样做时它往往会咬人;)

标签: c++ c types boolean


【解决方案1】:

为什么我们在 C 中使用 _Bool/bool (stdbool.h) 类型和在 C++ 中使用 bool 类型,如果它们在内存存储方面没有好处,因为它专门假装使用这些类型?

您已经在问题中提到了原因:

我们使用布尔类型来声明对象,它只能保存 0 或 1 的值

专门使用布尔数据类型的好处是它只能表示真或假。其他整数类型具有更多可表示的值,当您只需要两个时,这是不可取的。

为什么我不能只使用 int8_t 或 char 的类型(假设 char 在具体实现中包含 8 位(通常是这种情况))?

可以。事实上,直到 C99 标准,C 才具有布尔数据类型。请注意,使用int8_t 的缺点是不能保证所有系统都提供它。 char 的问题是它可能是签名的或未签名的。

但您不必这样做,因为您可以使用布尔数据类型。


这意味着当我将 true 或 false 与布尔类型一起使用时与我将它们与 char 或 int8_t 一起使用时存在差异。你能说一下这个区别吗?

考虑以下简单的例子:

int8_t i = some_value;
bool b = some_value;

if (i == true)
if (i)
if (b == true)
if (b)

对于int8_t,这两个条件句具有不同的行为,如果选择了错误的形式,就会为行为错误创造机会。对于布尔值,它们具有相同的行为并且没有错误的选择。


附:如果您想紧凑地存储多个布尔值(以每次读取和写入多条指令为代价),您可以使用 std::bitsetstd::vector&lt;bool&gt; 例如。在 C 中没有类似的标准库实用程序,但可以通过移位和屏蔽来实现此类功能。

【讨论】:

    【解决方案2】:

    效率不止一种。内存效率是其中之一。速度效率是另一个因素。

    最初的 C 语言根本没有 boolean 类型——通常程序员会使用 int 表示布尔标志,0 表示 false,1 表示 true。如果他们真的关心内存效率,他们可能会使用位图在一个字节中存储八个布尔值,但这通常只在内存非常稀缺的情况下才有必要。但是访问int 比访问int 然后解压缩其组成位更快

    _Bool/bool 是在 C99 中引入的。它反映了将布尔值存储在 int 中的常见做法。

    但是,它的优点是编译器知道它是一个布尔值,因此更难以意外地为其分配值 3,将其添加到整数等。

    当今的大多数编程语言都将布尔值存储在一个字节中。是的,它使用的内存是所需内存的 8 倍——但它速度很快,而且很少会同时运行如此多的布尔值,以至于浪费变得很严重。

    在许多编程语言中,实现与语言规范是分开的——Javascript 的规范没有说明 Javascript 运行时应如何存储 truefalse。但是,在 C99 中,您可以依赖 true 等效于整数 1

    如果布尔值确实占用了过多系统内存,您可以使用按位运算将 8 个布尔值存储在 unsigned char 中,或者在更大的类型中存储更多。

    如有必要,您可以为运行时操作执行此操作,或者仅在写入输出格式时执行此操作(如果问题是文件系统上的记录大小或网络数据包)。

    值得注意的是,在许多现代应用程序中,人们非常乐意在网络上或文件系统上将false 表示为 7 个字节 [ '"', 'f', 'a', 'l', 's', 'e', '"' ]

    【讨论】:

      【解决方案3】:

      同时拥有 bool 和 int 的原因之一是为了增加代码对那些追求并尝试维护它的人的理解。

      考虑这些

      布尔 b; 诠释 c;

      如果 (b == c)

      c = 2; b = 2;

      现在,我会说将布尔值(真或假)与数字进行比较很可能是错误的。所以像“if (b == 1)”这样的东西可能表示编码错误。我希望你同意 'b = 2' 是错误的。

      内存存储的好处(我不记得有任何地方声称使用布尔类型可以减少内存需求)并不是语言特性的唯一原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-06
        • 2013-11-14
        • 2021-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        相关资源
        最近更新 更多