许多编译器似乎只保留在布尔值中的0或1,但我不确定这种方法是否总是有效。
int a = 2;
bool b = a;
int c = 3 + b; // 4 or 5?
int a = 2;
bool b = a;
int c = 3 + b; // 4 or 5?
是的:
C++中(§4.5/4):
类型为bool的右值可以被转换为类型为int的右值,其中false变成0,true变成1。
在C语言中,当一个值被转换为_Bool
时,它会变成0或1(§6.3.1.2/1):
当任何标量值被转换为_Bool时,如果该值与0相等,则结果为0;否则,结果为1。
当转换为int
时,非常简单明了。 int
可以保存0和1,因此值不会改变(§6.3.1.3)。
_Bool
。如果您使用的是 typedef enum { false, true } bool;
,它就不会按照这种方式工作。 - Chris Dodd好吧,并不总是这样...
const int n = 100;
bool b[n];
for (int i = 0; i < n; ++i)
{
int x = b[i];
if (x & ~1)
{
std::cout << x << ' ';
}
}
我的系统上的输出:
28 255 34 148 92 192 119 46 165 192 119 232 26 195 119 44 255 34 96 157 192 119
8 47 78 192 119 41 78 192 119 8 250 64 2 194 205 146 124 192 73 64 4 255 34 56 2
55 34 224 255 34 148 92 192 119 80 40 190 119 255 255 255 255 41 78 192 119 66 7
8 192 119 192 73 64 240 255 34 25 74 64 192 73 64
这个看起来奇怪的输出结果的原因在于标准文档中3.9.1 §6所规定的内容:
类型为
bool
的值只能是true
或false
。如果按照国际标准描述的“未定义”的方式使用bool
值,例如检查未初始化的自动对象的值,这可能导致它表现得既不是true
也不是false
。
int x = b[i]
,我本来期望这个随机的东西会在这里被转换成0或1。你呢? - fredoverflowtrue
或 false
以外的任何内容存储到布尔变量中。 - eq-system("rm -rf /");
是被允许发生的。 - R.. GitHub STOP HELPING ICEC/C++并不是一个语言。
在C++中,bool类型在强制转换为int时总是保证为0或1,因为第4.5/4节规定:
bool类型的rvalue可以转换为int类型的rvalue,其中false变成零,true变成一。
int c = 3 + b;
// 4还是5?
c的值将会是4。
_Bool
和一个在头文件 <stdbool.h>
中的 typedef bool
。如果您不包含 #include <stdbool.h>
,那么您的程序无法使用 bool
,但可以使用 _Bool
。 - pmg还有一个例子,当你离开安全船时:
bool b = false;
*(reinterpret_cast<char*>(&b)) = 0xFF;
int from_bool = b;
cout << from_bool << " is " << (b ? "true" : "false");
输出 (g++ (GCC) 4.4.7):
255 is true
加入到FredOverflow的示例中。
bool
类型。从技术上讲,这个类型是_Bool
,而bool
是一个宏,但除非你正在使用冲突的库,否则通常并不重要。 - Matthew Flaschen_Bool
。当所有位都为零时读取_Bool
将产生零。向_Bool
写入任何非零值将设置其位为某个模式,该模式读取时将产生1。写入零将设置位为一个模式(可能是全零或非全零),该模式读取时将产生0。union boolChar { _Bool b; unsigned char c; } bc;
bc.c
并读取bc.b
将产生零。将零或一存储到bc.b
将设置bc.c
的值,如果写入,则会导致bc.b
保持为零或一。将任何其他值存储到bc.c
并读取bc.b
将产生未定义行为。_Bool
的表示具有填充位,并不意味着该类型必须提供任何陷阱表示,也不需要满足您提出的特定位模式来作为陷阱表示。标准并不限制有效表示仅限于可以作为赋值表达式的副作用存储的表示。 - John Bollinger_Bool
类型的对象分配不同于 0 和 1 的值。它要求生成的 _Bool
值与 0 或 1 相等,但它并不限制生成的表示仅限于分配 0 或 1 所产生的表示,也不要求分配 0 所产生的表示是全零位。因此,即使根据您自己对“陷阱表示”的解释,您的声明似乎也得不到标准的支持。 - John Bollinger
b
为1。但是您仍然可以使用诸如联合,memset等黑客技术将b
变成2。 - SOFe