if (false == x) { ...}
相对于:
if (!x) { ... }
和
if (false == f1()) { ...}
相对于:
if (!f1()) { ... }
我认为 if(false == ... 版本更具可读性。您同意吗,或者您可以提出其他技巧吗?它会一样快吗?谢谢。
这就是我不喜欢的原因!x:
if (25 == a->function1(12345, 6789) &&
45 == b->function1(12345, 6789) &&
!c->someOtherFunction(123)) { ... }
以下似乎更好:
if (25 == a->function1(12345, 6789) &&
45 == b->function1(12345, 6789) &&
false == c->someOtherFunction(123)) { ... }
我个人认为
if (!x) { ... }
的形式最具可读性,但现在它们都会产生相同的代码。
编辑:在您的示例中,我会执行以下操作:
if ( a->function1(12345, 6789) == 25 &&
b->function1(12345, 6789) == 45 &&
!(c->someOtherFunction(123))) { ... }
但这实际上只是个人喜好的事情。做对你来说最易读的事情。这不会有任何区别。
我认为 if(false == ... 版本更具可读性。你同意吗,或者你可以提出另一个技巧?
你做错了。
false == x
返回一个布尔值,显然必须与true
进行比较!
if (true == (false == x)) { ...}
会更好。但这又返回一个 bool,所以为了安全起见,并使代码更具可读性,我们最好这样做:
if (true == (true == (false == x))) { ...}
。等等。一旦你开始比较布尔值,你会在哪里停止?结果始终是另一个布尔值,为了保持一致,您必须将其与布尔值进行比较。
或者您可以学习理解您正在使用的语言,并使用
if (!x) { ...}
,它准确地表达了您想要的内容。
您认为哪一个更具可读性?
if (false == x) { ...}
翻译为“如果 true 则 false 等于 x”。if (!x) { ...}
翻译为“如果 x 不为真”。你能诚实、认真地说第一种形式“更具可读性”吗?你会用一句话来这么说吗? “如果 true 则 false 等于 x”?
它并没有更具可读性,它只是向任何阅读你的代码的程序员大喊“我不明白 if 语句或布尔值”。
C++ 在左侧保留以下关键字作为右侧运算符的替代:
and and_eq bitand && &= &
or or_eq bitor || |= |
xor_eq xor ^= ^
not not_eq compl ! != ~
如果您担心
!
迷路,not
会更加突出。
if ( a->function1(12345, 6789) == 25 and
b->function1(12345, 6789) == 45 and
not c->someOtherFunction(123)) {
...
}
一个好的编译器应该为两个代码块生成相同的代码。
但是,您应该更担心此示例中的短路评估,而不是担心
false == f1()
与 !f1()
:
if (25 == a->function1(12345, 6789) &&
45 == b->function1(12345, 6789) &&
!c->someOtherFunction(123)) { ... }
如果
b->function1()
调用的计算结果恰好不同于 25,某些编译器将生成跳过 c->someOtherFunction()
和 a->function1()
执行的代码 - 原因是,编译器已经知道整个 if ()
的结果在那一点上声明,这样它就可以跳转到正确的位置。
如果您的代码依赖于任何被跳过的函数修改的状态,您可能会得到令人讨厌的惊喜。
这是过早优化的一个例子(什么时候优化过早?)。但编译器会生成相同的代码(MSVC 2008 调试模式):
if (!bVal)
bVal = true;
if (bVal == false)
bVal = true;
//translates to
; 70 : if (!bVal)
cmp BYTE PTR $T5793[ebp], 0
jne SHORT $LN9@wmain
push OFFSET $LN10@wmain
call __RTC_UninitUse
add esp, 4
$LN9@wmain:
movzx eax, BYTE PTR _bVal$[ebp]
test eax, eax
jne SHORT $LN2@wmain
; 71 : bVal = true;
mov BYTE PTR $T5793[ebp], 1
mov BYTE PTR _bVal$[ebp], 1
$LN2@wmain:
; 72 :
; 73 : if (bVal == false)
cmp BYTE PTR $T5793[ebp], 0
jne SHORT $LN11@wmain
push OFFSET $LN10@wmain
call __RTC_UninitUse
add esp, 4
$LN11@wmain:
movzx eax, BYTE PTR _bVal$[ebp]
test eax, eax
jne SHORT $LN1@wmain
; 74 : bVal = true;
mov BYTE PTR $T5793[ebp], 1
mov BYTE PTR _bVal$[ebp], 1
您是否已分析并发现评估病情是一个热点? 如果没有,则执行您的编码标准要求的任何操作。
无论如何,两者都应该编译为相同的代码。 您可以通过检查编译器针对这两种情况生成的汇编代码进行检查。