这是一个纯粹迂腐的问题,以满足自己的好奇心。
我倾向于在问题中使用后一个选项(所以:if (boolCheck) { ... }
),而同事总是写前者(if (boolCheck == true) { ... }
)。我总是有点嘲笑他,并且从他第一次开始编程时,他总是把它解释为一种旧习惯。
但是今天我发现实际上写出整个== true
部分实际上可能需要额外的处理步骤,因为任何带有==
运算符的表达式都会被计算为布尔值。这是真的吗?
换句话说,据我所知,没有 == true行的选项可以松散地描述如下:
选项与 == true行更像是:
我说错了吗?或者也许任何普通的编译器/解释器都会消除这种差异?或者我忽略了什么,而且根本没有什么区别?
显然,在实际观察到的表现方面没有区别。就像我说的那样,我只是好奇。
编辑:感谢所有实际发布编译结果的人,以说明两种方法之间的步骤是否不同。 (看起来,大部分时间,他们都是,虽然只是轻微的。)
我只想重申,我不询问什么是“正确”的方法。我知道很多人喜欢一个人而不是另一个人。我也理解,从逻辑上讲,两者是相同的。我很好奇,如果CPU执行的实际操作对于两种方法都完全相同;事实证明,大部分时间(显然它取决于语言,编译器等),它们不是。
答案 0 :(得分:18)
我认为与真实的比较表明你的伴侣缺乏理解。 Bool应该被命名为避免这种情况(例如isAvaliable
:if (isAvailable) {...}
)。
答案 1 :(得分:16)
我希望通过任何半合半的编译器来优化差异。
(我刚用C#检查过,两种语法的编译代码完全相同。)
答案 2 :(得分:13)
编译器应该生成相同的代码。然而,与真实相比可以说更好,因为它更明确。一般来说,我不做明确的比较,但你不应该因为这样做而取笑他。
编辑:最容易辨别的方法是尝试。 MS编译器(cl.exe)在汇编中生成相同数量的步骤:
int _tmain(int argc, _TCHAR* argv[])
{
bool test_me = true;
if (test_me) {
004113C2 movzx eax,byte ptr [test_me]
004113C6 test eax,eax
004113C8 je wmain+41h (4113E1h)
printf("test_me was true!");
}
if (test_me == true) {
004113E1 movzx eax,byte ptr [test_me]
004113E5 cmp eax,1
004113E8 jne wmain+61h (411401h)
printf("still true!");
}
return 0;
}
此时问题是做测试而cmp有相同的成本吗?我的猜测是肯定的,尽管专家可能会指出差异。
实际结果是你不应该担心这一点。你可能有更大的性能鱼炒。
答案 3 :(得分:10)
重复问题(Should I use `!IsGood` or `IsGood == false`?)。这是我之前回答的指针:
具体测试技术 反对真或假是不好的做法 如果有问题的变量是真的 应该用作布尔值 (即使它的类型不是布尔值) - 特别是在C / C ++中。测试 真可以(也可能会)导致 微妙的错误。
有关详细信息,请参阅以下SO答案:
Should I use `!IsGood` or `IsGood == false`?
这是一个线程,详细说明为什么“== true”在更明确的细节中经常是错误的原因,包括Stroustrup的解释: https://qt-project.org/forums/viewthread/32642
答案 4 :(得分:4)
这是Python(2.6)反汇编:
>>> def check(x): return (bool(x) == True)
>>> import dis
>>> dis.dis(check)
1 0 LOAD_GLOBAL 0 (bool)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 LOAD_GLOBAL 1 (True)
12 COMPARE_OP 2 (==)
15 RETURN_VALUE
>>> def check2(x): return bool(x)
>>> dis.dis(check2)
1 0 LOAD_GLOBAL 0 (bool)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 RETURN_VALUE
我认为check
未被优化的原因是由于Python是一种动态语言。这本身并不意味着Python使用了一个糟糕的编译器,但它可以在这里进行一些类型推断。也许它在创建.pyd文件时有所不同?
答案 5 :(得分:4)
根据我的经验if (flag==true)
是不好的做法。
第一个论点是学术性的:
如果您有bool flag
,则可以是true
或false
。
现在,表达式
(flag==true)
再次,true
或false
- 它不再具有表现力,只有多余 - flag
不能比现在更“真实”或“更虚假”。只有在不明显flag
是布尔值的情况下才会“更加清晰” - 但是有一种标准方法可以修复适用于所有类型的方法:选择更好的名称。
超越理性,以下将“更好”:
((flag==true)==true)
第二个论点是务实的,特定于平台的
C和早期的C ++实现没有真正的“bool”类型,因此标志有不同的约定,最常见的是非零是真的。 API返回基于整数的BOOL类型并不常见,但不强制返回值为0或1.
某些环境使用以下定义:
#define FALSE 0
#define TRUE (!FALSE)
祝你好运if ((1==1) == TRUE)
此外,一些平台使用不同的值 - 例如VB互操作的VARIANT_BOOL
为short
,VARIANT_TRUE
为-1
。
使用这些定义混合库时,与true的显式比较很容易就是伪装成良好意图的错误。所以,不要。
答案 6 :(得分:2)
MSVC ++ 6.0编译器为这两种形式生成略有不同的代码:
4: if ( ok ) {
00401033 mov eax,dword ptr [ebp-8]
00401036 and eax,0FFh
0040103B test eax,eax
0040103D je main+36h (00401046)
....
7: if ( ok == true ) {
00401046 mov ecx,dword ptr [ebp-8]
00401049 and ecx,0FFh
0040104F cmp ecx,1
00401052 jne main+4Bh (0040105b)
如果我能正确记住我的8086时序,那么以前的版本应该会稍快一些: - )
答案 7 :(得分:2)
这会涉及特定语言以及他们认为“真实”的价值观。以下是两个常见问题:JavaScript和PHP。
这两种语言中的三重等于运算符确保您确实在检查布尔类型的真值。例如,在PHP中,if ($value)
的检查可能与if ($value==true)
或if ($value===true)
不同:
$f = true;
$z = 1;
$n = null;
$a = array(1,2);
print ($f) ?'true':'false'; // true
print ($f==true) ?'true':'false'; // true
print ($f===true) ?'true':'false'; // true
print "\n";
print ($z) ?'true':'false'; // true
print ($z==true) ?'true':'false'; // true
print ($z===true) ?'true':'false'; // false
print "\n";
print ($n) ?'true':'false'; // false
print ($n==true) ?'true':'false'; // false
print ($n===true) ?'true':'false'; // false
print "\n";
print ($a) ?'true':'false'; // true
print ($a==true) ?'true':'false'; // true
print ($a===true) ?'true':'false'; // false
print "\n";
print "\n";
我希望每天发言的语言会告诉我们如何看待这个问题。
答案 8 :(得分:2)
“boolCheck == true”语法可能有一些理由取决于您正在测试的变量的名称。
例如,如果变量名称为“state”,那么您可以拥有:
if (state) {
...
}
或者你可以
if (state == true) {
...
}
在这种情况下,我认为后一种形式更清晰,更明显。
另一个例子是像“启用”这样的变量,在这种情况下,第一种形式更清晰。
现在有一个名为“state”的布尔变量是不好的做法,但你可能无法控制它,在这种情况下,“== true”语法可以提高代码的可读性。
答案 9 :(得分:1)
这取决于编译器。两种情况都可能有优化。
答案 10 :(得分:1)
测试等于true会导致错误,至少在C中:在C中,'if'可以用于整数类型(不仅仅是布尔类型),并接受任何非 - 零价值;然而,符号“TRUE”是一个特定的非零值(例如1
)。这对于位标志来说很重要:
if (flags & DCDBIT)
{
//do something when the DCDBIT bit is set in the flags variable
}
所以给出这样的函数......
int isDcdSet()
{
return (flags & DCDBIT);
}
...表达式“if(isDcdSet())”与“if(isDcdSet()== TRUE)”不同。
反正;我认为优化编译器应该优化任何差异(因为没有逻辑差异),假设它是一种具有真正布尔值(而不仅仅是整数)类型的语言。
答案 11 :(得分:0)
没有逻辑上的区别,假设没有内部类型转换,例如测试fstream。
ifstream fin;
...
if( ! fin)
...
答案 12 :(得分:0)
如果您正在使用可空的布尔值,则可能不一样。
示例:
Bool? myBool = true
if(myBool) // This will not compile
if(myBool == true) //this will compile
答案 13 :(得分:0)
恕我直言,使用if (boolCheck == true)
形式是一个坏主意,原因很简单:如果你不小心输入一个'等于'符号而不是双(即if (boolCheck = true)
),它将分配{ {1}}到true
并且将始终返回true,这显然是一个错误。当然,大多数现代编译器在看到它时会显示警告(至少C#编译器会这样做),但许多开发人员只是忽略警告......
如果您想要明确,您应该更喜欢这种形式:boolCheck
。这样可以避免意外分配变量,如果忘记'等于'符号,将导致编译错误。