为什么我不能使用“== true”来检查变量是否具有值?

5

if(10)这个条件为真,但if(10 == true)却是假的。有人可以告诉我为什么第一个条件会将数字转换为布尔值,但第二个条件却没有呢?


2
尝试 if(!!10 == true) - BLUEPIXY
2
“true” 的值可以是任何东西(我经常在各种编译器中看到 1、!0 和 2)。然而,任何不为 0(false)的值都可以进行测试,并且测试将返回“true”。这就是为什么您可以使用:if(10) 而不能使用 if( 1== true)。在失败的 'if' 语句中,值 1 被与用于表示“true”的值进行比较。无论如何,10 不是 1(也不是 2 或 !0),因此比较的结果是 false。 - user3629249
1
在C++中,true是一个布尔值,如果提升为整数,则会精确地转换为1。我相信这与C99一致,考虑到包含了stdbool.h - rici
4个回答

22

if (10)等价于if (10 != 0),而if (10 == true)相当于if (10 == 1)(因为true被提升为类型为int的值1)。

通俗易懂地说:两件事情恰好满足某种属性并不意味着它们自动相同。

例如,甜甜圈和飞盘都是圆形的,但这并不意味着一个甜甜圈等于一个飞盘。整数和布尔值都可以在布尔上下文中进行评估,但这并不意味着每个被评估为真的整数都等于每个真布尔值。


1
我不确定你所说的外行术语是否真的是外行术语。我觉得它们很深奥! :) - SergeyA
5
C标准6.8.4.1.2关于“if”语句的说明是:“在两种形式中,如果表达式与0不相等,则执行第一个子语句。” 我理解虽然从技术上讲存在差异(因为它们_字面上_不是同一个程序,在if(10 != 0)中,如果表达式10!=0与0不相等,则执行语句体),但在C语言中将其写出来对于理解很有帮助。 - Paul Hankin
在C中,如果条件语句 if( 10 ) 执行时会直接执行。而在C++中则变成了 if( true )。然而,若为 if( 10 != 0 ),在C语言中会变成 if( 1 )(不是 if( 10 )),在C++中则为 if( true )。编译器需要将 10 != 0 优化为 1true。编译器解析和评估的是二进制表达式 10 != 0 - lllllllllll
1
@SergeyA:就像这样:你去过中国吗?没有?那么你一定认识我的姐姐——她也从未去过中国。 - Kerrek SB
1
既然我们正在谈论类型和提升:请注意,在C和C++中,表达式10 == 1的语义略有不同:在C++中,该表达式具有bool类型,而在C中,它具有int类型并且取值为01。(直到最近,C才没有布尔类型。) - Kerrek SB
显示剩余2条评论

1
if( ... )
{
     // if statement
}

要在C++中执行if语句,...应该有一个true值。
当你写了if(10) {//一些有用的东西}时,
我认为10被视为int而不是bool变量。然后应该应用以下逻辑。
if( 10 ) -> if( bool( 10 ) ) -> if( true )

当你写下 if(10 == true){ //something useful } 时,根据C++标准,背后应该有以下逻辑。
if( 10 == true ) -> if( 10 == int( true ) ) -> if( 10 == 1 ) -> if( false )

你可以写类似这样的内容

if( 10 != false )

或者

if( !!10 == true )

也就是说。
if( ( bool ) 10 == true ) // alternatively, if( bool ( 10 ) == true )

在旧版的C语言(在C99之前),不存在false或true,但存在0或非0值。
在现代的C语言(从C99开始),存在false或true(),但它们只是0和1的语法糖。
if( 10 ) // evaluates directly since 10 is non-zero value

if( 10 == true ) -> if( 10 == 1 ) -> if( 0 )

@GManNickG 什么是“关键字”?我的回答意思是,true 是表示 1 的 1 位二进制的语法糖(bool(1)0b1)。 - lllllllllll
如果您想了解语言的详细信息,请阅读标准;关键字是解析的语法结构。此外,布尔值不是单个位,它们至少为1字节,因为所有类型都具有sizeof(T) >= 1,包括bool - GManNickG
@GManNickG 当我在任何C++程序中输入0或1时,g++编译器会看到什么?它是0b0或0b1,false或true还是其他什么? - lllllllllll
@GManNickG truefalse是否是分别代表10的8位表示的语法糖? - lllllllllll
"4.12. 零值、空指针值或空成员指针值被转换为false;" 所以,是的,我错了。0被转换为false,但反过来不行。 - lllllllllll
显示剩余5条评论

-1

因为它们是完全不同的东西。

在 C 语言中,任何非 false 的值都会自动被视为 true,并且 C 有一个非常严格的 false 定义。

你可以将 if(10) 理解为 if(10 != false)

同样地,if (10 == true) 可以理解为 if((10 == true) != false)


-2

10 明显不是 true,因为 10 是一个数字而 true 是一个布尔值。

当你在 if 语句中时,编译器必须评估条件直到它达到 true 或 false。如果它没有达到 true 或 false,它必须将其转换为 true 或 false。通常情况下,0 会被评估为 false,而其他所有值都会被评估为 true。

所以 if(-1) 是 true,if(234) 也是 true,以此类推。

表达式 10 == true 已经评估为 false,因此不需要进一步的转换。if(10) 既不是 true 也不是 false,所以编译器必须使用我们上面的规则进行转换,它变成了 true。


在开始时错误的推理是 1 == true 是正确的,即使 1 是一个数字是一个 int 常量,而 true 是一个 bool 常量。 - Antti Haapala -- Слава Україні
这比那要复杂一些,而且在 C 和 C++ 中也有所不同。在 C++ 中,“if”语句的控制表达式会被*上下文转换为“bool”。在 C 中,控制表达式会与0进行相等比较。 - Kerrek SB
在C语言中,truefalse是宏,会扩展为10,就像另一个整数常量一样。 - Antti Haapala -- Слава Україні
感谢您的澄清! - Omar Shehata

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