33

我正在阅读C++ 编程语言。Stroustrup 在其中指出sizeof(char) == 11 <= sizeof(bool)。具体取决于实施。为什么像布尔值这样简单的值会占用与字符相同的空间?

4

7 回答 7

69

在现代计算机体系结构中,字节是内存的最小可寻址单元。要将多个位打包到一个字节中,需要应用额外的位移操作。在编译器级别,这是内存与速度要求的权衡(在高性能软件中,那些额外的位移操作可能会不必要地增加和减慢应用程序的速度)。

于 2008-11-05T22:00:12.087 回答
23

因为在 C++ 中,您可以获取布尔值的地址,而大多数机器无法寻址单个位。

于 2008-11-05T22:02:22.707 回答
12

它占用相同的空间,因为您可以在内存中写入的最小空间量是单个字节。两个值都存储在一个字节中。尽管理论上您只需要 1 位来表示布尔值,但您仍然必须有一个完整的字节来存储该值。

于 2008-11-05T21:56:20.440 回答
5

从理论上讲,布尔值只需要一个位,但是处理少于 1 个字节的数据是很麻烦的。你需要更多的指令来完成任何事情,而你并没有真正受益。

如果要将多个布尔值打包到一个字节中,可以使用位域结构

于 2008-11-05T21:56:45.073 回答
3

字节是内存的最小可寻址单元。

考虑以下代码:

    bool b[9];
    bool *pb0 = &b[0];
    bool *pb1 = &b[1];

    for (int counter=0; counter<9; ++counter)
    {
         // some code here to fill b with values
         b[counter] = true;

    }

如果 bool 存储为 1 位,则 pb0 将等于 pb1,因为两者具有相同的地址。这显然是不可取的!

此外,循环中的赋值将导致非平凡的汇编代码。它将在循环的每次迭代中涉及不同的位移。在高性能软件中,那些额外的位移操作会不必要地减慢应用程序的速度。

STL 库在空间确实很重要的情况下提供了一种解决方法。使用 std::vector<bool> 会将 bool 存储为 1 位。上面例子的悖论不适用,因为

  • operator[] 的重载隐藏了位移操作的严格性
  • 使用迭代器代替指针为实现提供了额外的灵活性
于 2008-11-06T11:17:24.987 回答
2

实际上,在我所知道的大多数实现中,sizeof(bool) == sizeof(int)。“int”旨在成为 CPU 使用效率最高的数据大小。因此,没有特定大小的事物(如“char”)与 int 大小相同。如果每个对象有大量它们,您可能希望实现一种打包它们以进行存储的方法,但在正常计算期间,它应该保留其原始大小。

于 2008-11-05T22:04:01.313 回答
2

C++中有一个叫做vector的东西,它试图利用理论上你可以在一个字符中存储8个布尔值的事实,但它被C++标准委员会广泛认为是一个错误。“有效的stl”这本书实际上说“不要使用它”。这应该让你知道它是多么棘手。

顺便说一句:Knuth 有一本书专门介绍按位运算。Boost 还有一个专门用于以更高效的内存方式处理大量位的库。

于 2008-11-05T22:09:03.487 回答