为什么下面的代码只有当a = 1时才返回true?

13

为什么下面的代码只有当a = 1时返回true?

main(){
int a = 10;
if (true == a)
     cout<<"Why am I not getting executed";
}
11个回答

38

当一个布尔值为真时转换为整数,它总是被转换为1。因此,你的代码等同于:

main(){
   int a = 10;
   if (1 == a)
      cout<<"y i am not getting executed";
   }

这是C++标准的一部分,因此您可以预期每个符合C++标准的编译器都会发生这种情况。


我认为你的意思是“它总是被转换为1”,而不是“它总是被转换为true”。 - John Carter
1
也许可以简单解释一下为什么是将bool转换为int,而不是将int转换为bool?我是说,“因为C++标准规定了这样做”已经覆盖了大部分情况,但还是…… - Steve Jessop
将“true”转换为int的值是编译器特定的,还是属于标准的一部分? - David Hill
这是标准的一部分(已编辑包括它及其在标准中的说明链接)。 - paradoja
1
原始代码的作者可能在想:if( true == bool(a) ),这将把10转换为true。也就是说,bool(5) != 5。 - Aaron

26

你的打印语句没有执行的原因是因为布尔值被隐式转换成数值而不是相反。也就是说,你的if语句等同于这个条件:if (1 == a)

你可以通过首先显式将其转换为布尔值来解决这个问题:

main(){
int a = 10;
if (((bool)a) == true)
     cout<<"I am definitely getting executed";
}

在C/C++中,false表示为0。

其他所有值都表示为非零。有时是1,有时是其他任何值。因此,您不应该测试相等性(==)是否为真。相反,您应该测试相等性是否为假。因为false只有一个有效值。

在这里,我们测试所有非false值,任何一个都可以:

main(){
int a = 10;
if (a)
     cout<<"I am definitely getting executed";
}

这是第三个例子,证明将任何被视为false的整数与false(即0)进行比较是安全的:

main(){
int a = 0;
if (0 == false)
     cout<<"I am definitely getting executed";
}

使用函数式转换或C++强制类型转换。C风格的转换是不好的。使用'bool(a)'或'static_cast<bool>(a)'。 - Aaron
Aaron,抱歉这是无意义的 :) “函数式转换”在语义上等同于(T)x样式转换,并且还会引入歧义。如果有什么区别,那只是品味问题,但可以说T(x)比(T)x更具问题。 - Johannes Schaub - litb

5

您的布尔值被提升为整数,并变成了1。


3
在C和C++中,0表示假,而非零表示真。
if ( 0 )
{
// never run
}

if ( 1 )
{
// always run
}

if ( var1 == 1 )
{
// run when var1 is "1"
}

当编译器计算布尔表达式时,它必须生成0或1。此外,有几个方便的typedef和define,允许您在表达式中使用“true”和“false”而不是1和0。

因此,您的代码实际上看起来像这样:

main(){
int a = 10;
if (1 == a)
     cout<<"y i am not getting executed";
}

您可能需要:

main(){
int a = 10;
if (true == (bool)a)
     cout<<"if you want to explicitly use true/false";
}

或者只是:

main(){
int a = 10;
if ( a )
     cout<<"usual C++ style";
}

2

因为true等于1。如果你想测试一个非零值,只需写if(a)。


2
哎呀。如果你想测试一个非零值,写if(a!=0)。多打三个字符来表达你实际的思想,而不是说语言让你的思想等价于什么你正在思考的东西。便宜。 - Steve Jessop
这是额外的5个字符,因为我会在运算符和其操作数之间添加空格 ;) - OregonGhost
哦,那样的话,我明白了 ;) 我曾经经常使用if(a)来表示指针,意思是“如果有一个a”。但最终我决定对我来说这并没有帮助,于是放弃了它。 - Steve Jessop
我也不再使用它了,因为我今天大多数的代码都是用C#编写的,其中int不能隐式转换为bool。C++甚至鼓励这种风格,例如fstream,在那里你可以像if (!myfile) {}这样测试。也许不要像这样测试数字可能是一个好建议。 - OregonGhost

1

我建议您切换到一个可以警告您此类问题的编译器... (VC++ 出现以下警告: warning C4806: '==' : unsafe operation: no value of type 'bool' promoted to type 'int' can equal the given constant; 我手头没有其他编译器.)

我同意 Lou Franco 的观点 - 您要判断一个变量是否大于零(或不等于它),请测试它。

如果您不知道最后一步,编译器隐含完成的所有操作都是危险的。


0

这是大多数人编写此类代码的方式:

main(){
int a = 10;
if (a) // all non-zero satisfy 'truth'
     cout<<"y i am not getting executed";
}

我也看到过:

main(){
int a = 10;
if (!!a == true) // ! result is guaranteed to be == true or == false
     cout<<"y i am not getting executed";
}

-1
我不会期望那段代码被定义,你也不应该依赖于编译器给你的任何行为。可能 true 被转换为 int (1),而 a 没有像你期望的那样被转换为 bool (true)。最好写出你的意思 (a != 0),而不是依赖于这个(即使它被定义了)。

-1

不同于0(即假)的东西并不一定是真的(即1)


-2

因为在C/C++中布尔类型是一个位,true代表1,false代表0。

更新:如评论所说我的原始答案是错误的,请忽略它。


C/C++并不规定布尔类型一定是一个比特。在C++中,布尔类型的大小取决于实现方式。C语言没有布尔类型——它实际上是一个整数。 - Steve Fallows
C99有一种布尔类型,可以通过#include <stdbool.h>启用。但我同意,在C或C++中,布尔类型不是位。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接