【问题标题】:What is bool in C++?C++ 中的布尔值是什么?
【发布时间】:2011-03-17 05:12:26
【问题描述】:

我遇到了一些非常有趣的代码,让我想知道 bool 是什么。我一直认为它是一种原始类型,例如 int 或 char 或 long。但是今天,我看到了这样的东西:

void boolPtrTest()
{
    bool thisBool = true;

    boolPtrHere(thisBool);

    printf("thisBool is %s\n", thisBool ? "true" : "false");
}

void boolPtrHere(bool& theBool)
{
    theBool = false; // uhh, dereferencing anyone?
}

并且此代码运行 - 没有错误 - 并打印“thisBool is false”!

为了让这更奇怪,我运行了以下代码:

bool myBool = new bool();

...代码运行良好!

在你问我一个“noobish”问题之前给我投反对票

这是我的问题: bool 是什么?它是在逐个实现的基础上定义的吗?从上面显示的证据来看,我会说这是一个类。从实际的角度来看(忽略上述内容),将 bool 定义为 int / char 的 typedef 或将其定义为 #define 似乎也是合适的。但是如何知道它是什么(这会影响您如何对待它)?

编辑:我想我会补充一点,我正在使用 VS 2008。

【问题讨论】:

  • 您只是不理解 C++ 引用的概念吗?
  • 这不是 Java,顺便说一句。 bool myBool = new bool(); 没有做你怀疑的事情(导致内存泄漏,括号是不必要的)。
  • 对于一些愚蠢但有趣的行为来说这是怎么回事: bool myBool = new bool(false); // myBool 现在等于 'true'
  • @adan_0:为什么不应该运行? “呃,取消引用任何人”评论是什么意思?您似乎误解了 C++ 引用的工作原理,但很难确定。您能向我们描述一下您对代码的期望吗?
  • 这就是为什么您从不尝试从其他人那里获得知识来学习一门语言。它们是两种不同的语言,不要混用!你只会把自己搞砸。学习一门语言的唯一方法是从头开始,所以拿起一本书从那里开始。 stackoverflow.com/questions/388242/…

标签: c++ boolean


【解决方案1】:

我只是没有看到你描述的“怪异”。

你声明了一个bool,初始化为true。 通过调用一个函数并通过引用传递它,您可以将其值更改为false

然后你打印出这个值,它就起作用了。 问题是什么?更准确地说,有什么证据表明正在发生奇怪的事情?

由于您想了解详细信息,bool 可能是一个字节(char)或int。 当您将其分配为真/假时,它会获得值 0 或 1。(使用 sizeofprintf("%d") 来检查它)。

我怀疑真正的问题是您不了解boolPtrHerepass-by-reference。您没有将指针传递给布尔值。您正在通过内存引用传递实际值。 (将其视为不需要取消引用的指针)。

【讨论】:

  • 但是!但!但!该函数在此处称为 bool PTR,他们只是传递一个 bool!
  • 你的函数名有误,仅此而已。它并不能证明 bool 是某种魔法,实际上它是一种原始类型。
【解决方案2】:
void boolPtrHere(bool& theBool)
{
    theBool = false; // uhh, dereferencing anyone?
}

这段代码没有任何问题。 通过引用获取布尔值。不需要取消引用。

bool myBool = new bool();

new 返回一个地址,该地址转换为true,因为它从不返回非零值。这是一种常见的转换,尤其是在 C 代码中:

int* my_int = malloc(10 * sizeof(int));
if (!my_int) // my_int is converted to bool
    memory_error();

【讨论】:

  • 好吧,除非在指定nothrow语义的内存耗尽的情况下,否则永远不会。但是,是的,我想那是迂腐。 :)
  • 该表达式,如所写,永远不会导致myBool 为假。其他表达式显然可以,但列举它们并没有什么好处。
  • @Dennis:它可能在异常被禁用并且所有new 表达式都隐含nothrow 的功能失调环境中。在这种情况下,我处理过不止一个代码库。
  • @Mike:但这是非标准的。任何人都可以尝试加入极端情况,但是您不再使用标准 C++。在标准 C++ 中 new bool 从不抛出
  • @Mike:没关系。我刚刚重新阅读了我的评论并意识到我写了new bool never throws...我的意思是永远不会返回 0! :s
【解决方案3】:

bool 是基本类型; truefalse 是已初始化的 bool 类型的对象仅有的两个值。

您的函数boolPtrHere() 没有指向bool 的指针(这将是bool*);它需要一个bool引用。它的工作原理与 C++ 中的任何其他参考一样。

至于你的最后一个例子:

bool myBool = new bool();

在 C++ 中,指针可隐式转换为 bool。新表达式返回一个指向动态分配的bool 对象的指针。该指针随后被转换为bool 并存储在 myBool 中。如果指针为空,那么 myBool 将为假;否则它将为真(因为new 永远不会返回 null,myBool 在这种情况下将始终为真)。

【讨论】:

    【解决方案4】:

    Bool 是定义良好的原始整数类型,就像 int、char 等一样。它也有到其他整数类型的数学转换,这有时会让人感到困惑,但我不认为这是你目前的困惑。

    我不确定您对包含的第一个代码段有什么特别之处。布尔值可以是引用,就像其他任何东西一样。看来您可能对那里的指针和引用之间的区别感到困惑。

    至于第二个代码sn-p,那就有点棘手了。那实际上是内存泄漏,如果我们换一种方式写,应该会更清楚它在做什么:

     bool myBool = (new bool) != 0 ? true : false;
    

    从中,您可以看到它所做的是从堆中分配一个布尔值,然后将结果与 NULL/0 进行比较,并使用该比较的结果来分配给布尔值。请注意,最初从堆中分配的值被泄露。我有点惊讶这不会为您生成编译器错误,我怀疑在某些编译器上它会。

    【讨论】:

      【解决方案5】:

      引用不需要被取消引用。指针可以。

      【讨论】:

        【解决方案6】:

        这样想:

        typedef enum { false=0, true=1 } bool;
        

        【讨论】:

          【解决方案7】:

          我一直认为它是 原始类型,如 int 或 char 或 长。

          您似乎是从 Java 的角度来看待 C++。在 Java 中,原始类型总是按值传递,而其他类型总是引用。

          C++ 不同。如果以这种方式声明,任何类型都可以是引用。也可以声明int &xint *x,所以bool没有什么奇怪的。

          【讨论】:

            【解决方案8】:

            关于 bool 的一个非常小的惊喜是 sizeof(bool) >= 1。 bool 需要一个完整字节的存储空间。这样它们就可以有一个唯一的地址并被指向,就像在 boolPtrHere 函数中一样。

            【讨论】:

            • 由于您所说的原因,sizeof(bool) 至少为 1,但可以更大。
            • 它的大小是实现定义的,不一定是1。
            猜你喜欢
            • 1970-01-01
            • 2011-01-29
            • 2013-08-05
            • 2022-11-08
            • 2016-03-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多