首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果bool和_Bool占用内存中的一个字节,它们为什么只能存储0或1呢?

如果bool和_Bool占用内存中的一个字节,它们为什么只能存储0或1呢?
EN

Stack Overflow用户
提问于 2020-01-22 15:48:49
回答 4查看 1.1K关注 0票数 3

我阅读了这个问题的答案:为什么在c++中一个字符和一个bool大小相同?,并进行了一个实验,以确定_Boolbool内存中分配的字节大小(我知道boolstdbool.h_Bool的宏,但为了完整起见,我也使用了它) C中的对象,以及在我的实现LinuUbuntu12.4上的C++中的bool对象:

C组:

代码语言:javascript
运行
复制
#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;
}

输出:

代码语言:javascript
运行
复制
the size of bin1 in bytes is: 1
the size of bin2 in bytes is: 1

对于C++:

代码语言:javascript
运行
复制
#include <iostream>

int main()
{
    bool bin = 1;

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

    return 0;
}

输出:

代码语言:javascript
运行
复制
the size of bin in bytes is: 1 

因此,布尔类型的对象,无论是特定的C或C++,都占用内存中的1字节(8位),而不仅仅是1位。

我的问题是:

  • 为什么C中的bool_Bool类型的对象和C++中的bool类型的对象只能够存储01的值,如果它们在内存中占用一个字节,可以容纳256个值?

当然,它们的目的只是表示01truefalse的值,但是哪个单元或宏决定它只能存储01

另外,但不是我的主要问题:

  • 如果布尔类型的值被意外地在内存中修改为更大的值,会发生什么,因为它可以以这种方式存储在内存中?

*无意中,我的意思是:修改为“不可探测的手段”- 什么是“无法检测的意思”,它们如何改变C/C++程序的对象?或不适当的分配f.e。bool a; a = 25;

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-01-22 15:54:39

C语言限制了可以存储在_Bool中的内容,即使它能够保存除0和1以外的其他值。

C标准的第6.3.1.2节提到了关于转换到_Bool的以下内容

当将任何标量值转换为_Bool时,如果该值比较等于0,则结果为0;否则,结果为1。

C++17标准在第7.14节中有类似的语言:

可以将算术、非作用域枚举、指针或成员类型指针的prvalue转换为bool类型的prvalue。零值、空指针值或空成员指针值转换为false;任何其他值都转换为真。对于直接初始化(11.6),可以将std::nullptr_t类型的prvalue转换为bool类型的prvalue;结果值为false。

因此,即使您试图将其他值赋值给_Bool,语言也会将该值转换为0或1表示C,将值转换为truefalse表示C++。如果试图通过指向不同类型的指针写入_Bool来绕过这一点,则调用未定义行为

票数 5
EN

Stack Overflow用户

发布于 2020-01-22 16:07:23

回答C++:

因此,布尔类型的对象,无论是特定的C或C++,都占用内存中的1字节(8位),而不仅仅是1位。

这仅仅是因为C++内存模型中的基本存储单元是字节

为什么类型为. bool在C++中的对象只能存储0或1的值,如果它们在内存中占用一个字节,可以容纳256个值? 但是哪个单元或宏决定它只能存储0或1?

这里的假设是错误的。在C++中,bool不包含01,它包含falsetruehttp://eel.is/c++draft/basic.fundamental#10

如何在内存中表示这两个值是,直到实现为止。实现可以使用01,或者0255,或者0<any nonzero value>,或者它真正想要的任何东西。在检查01内存时,不能保证找到bool,因为.

  • 如果将整数或指针“赋值”给bool,则根据通常的规则:http://eel.is/c++draft/conv.bool#1,将其隐式转换为truefalse
  • 如果您从bool中“读取”一个整数,如果它包含值0 false1,则它将被隐式转换为truehttp://eel.is/c++draft/conv.prom#6

不管bool值是如何在内存中表示的,编译器的任务是确保上述两件事都是正确的。请记住,C++是在抽象机器上指定的,您的程序只需要在抽象机器上执行。

如果布尔类型的值在内存中被意外地修改为更大的值,会发生什么情况?

未定义的行为。见其中之一:

票数 3
EN

Stack Overflow用户

发布于 2020-01-22 15:57:30

(回答C.)

但是哪个单元或宏决定它只能存储0或1?

在典型的C实现中,编译器实现了这一点。编译器决定(或设计)在操作_Bool值时使用哪些指令。它可以使用一个根据字节是零还是非零来设置条件代码的指令来测试一个_Bool,也可以用一个根据低位(例如)是零还是非零来设置条件代码的指令来测试它。C标准并没有对此提出任何要求。每个C实现都可以自由选择自己的实现。

如果布尔类型的值在内存中被意外地修改为更大的值,会发生什么情况?

这取决于C实现。如果实现测试的是零或非零,则可以将更大的值视为1。如果实现使用该值,则可以根据其低位来处理更大的值。如果实现根据具体情况使用不同的指令,则更大的价值可能在不同的情况下表现得不同。一个更大的价值也可能导致结果,否则将是荒谬的。例如,考虑到int x = 4;和一些通过写入内存而不适当地修改的_Bool yint z = x + y;可能将z设置为10,尽管如果y是正确的_Bool,则只有4或5是可能的。当您将类型的表示修改为表示由实现定义的适当值的位以外的东西时,生成的行为不是由C标准定义的,通常也不是由C实现定义的。

给布尔类型分配一个更大的值甚至是可能的和允许的吗?

不,赋值将右操作数转换为赋值表达式的类型(这是左操作数的类型,但作为值而不是lvalue除外)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59863467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档