-3

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


我们使用布尔类型来声明对象,这些对象只能保存 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 位,因为它通常只需要。

这里讨论的原因是:为什么 char 和 bool 在 c++ 中的大小相同?. 这不是我的问题。


我的问题是:

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

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

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

非常感谢您的参与。

4

3 回答 3

4

为什么我们要使用 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,这两个条件句具有不同的行为,如果选择了错误的形式,就会为行为错误创造机会。对于布尔值,它们具有相同的行为并且没有错误的选择。


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

于 2020-01-22T14:51:46.157 回答
1

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

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

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

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

今天的大多数编程语言都将布尔值存储在一个字节中。是的,它使用的内存是所需内存的 8 倍——但它速度很快,而且很少会同时有这么多布尔值导致浪费变得很严重。

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

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

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

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

于 2020-01-22T14:54:13.877 回答
0

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

考虑这些

布尔 b; 诠释 c;

如果 (b == c)

c = 2; b = 2;

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

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

于 2020-01-22T15:51:19.417 回答