为什么使用! 当转换为BOOL BOOL?
以这种方式将整数转换为布尔值的原因是什么?
bool booleanValue = !!integerValue;
而不是仅仅
bool booleanValue = integerValue;
我所知道的是在VC ++ 7中,后者将导致C4800警告 ,而前者不会。 两者之间还有其他的区别吗?
与“!!”的问题 成语是它很简单,很难看,很容易误以为是一个错字,容易掉一个“!”,等等。 我把它放在“看看我们可以用C / C ++多么可爱”的类别中。
只要写bool isNonZero = (integerValue != 0);
… 清楚。
历史上, !!
成语是用来确保你的bool确实包含了bool
likevariables中预期的两个值之一,因为C和C ++没有真正的bool
types,我们用int
伪造它。 与“真正的” bool
现在这是一个问题。
但使用!!
是一个有效的方法来logging(对于编译器和任何未来在你的代码中工作的人)是的,你确实打算把这个int
bool
一个bool
。
因为!integerValue表示integerValue == 0而!! integerValue因此意味着integerValue!= 0,这是一个返回一个bool的有效expression式。 后者是一个信息丢失的演员。
这是因为C语言(和一些预标准的C ++编译器)也没有bool
types,只是int
。 所以int
被用来表示逻辑值: 0
应该是false
,其他的都是true
。 那!
运算符从0
和0
返回1
。 双重!
被用来反转这些,并在那里确定这个值只是0
或1
这取决于它的逻辑值。
在C ++中,由于引入了适当的bool
types,因此不再需要这样做。 但是你不能只更新所有的遗留源,而且你不应该因为C和C ++的向后兼容(大部分时间)。 但是许多人仍然这样做,出于同样的原因:保持自己的代码向后兼容那些仍然不懂bool
的旧编译器。
这是唯一真正的答案。 其他答案是误导。
另一种select是三元运算符似乎生成一行less汇编代码(无论在Visual Studio 2005中):
bool ternary_test = ( int_val == 0 ) ? false : true;
这会产生汇编代码:
cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _ternary_test$[ebp], al
与:
bool not_equal_test = ( int_val != 0 );
这产生:
xor eax, eax cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _not_equal_test$[ebp], al
我知道这不是一个巨大的差异,但我很好奇,只是想我会分享我的发现。
一个布尔只能有两个状态,0和1.一个整数可以有一个从-2147483648到2147483647的任何状态,假设一个有符号的32位整数。 一元! 如果input为0,则操作员输出1,如果input是除0之外的任何其他输出,则输出0。因此!0 = 1且!234 = 0。 只需切换输出,使0变成1,1变成0。
所以第一个语句保证布尔值将被设置为等于0或1而不是其他值,第二个语句不会。
!!
是一种转换为bool
的惯用方式,它可以阻止Visual C ++编译器对这种转换的低效率的愚蠢警告。
我从其他答案和评论中看到很多人不熟悉这个习语在Windows编程中的用处。 这意味着他们没有做任何严肃的Windows编程。 盲目地假设他们遇到的是有代表性的(不是)。
#include <iostream> using namespace std; int main( int argc, char* argv[] ) { bool const b = static_cast< bool >( argc ); (void) argv; (void) b; }
> [d:\ dev \ test] > cl foo.cpp Foo.cpp中 foo.cpp(6):警告C4800:'int':强制值为bool'true'或'false'(性能警告) [d:\ dev的\testing] > _
至less有一个人认为,如果一个新手不认识它的意思,那么它就是不好的。 那真是愚蠢。 新手不认识或理解的东西有很多。 编写一个代码,以便任何新手都能理解它,这对于专业人员来说并不是什么东西。 甚至没有学生。 从排除新手无法识别的操作符和操作符组合的path开始……那么我没有给出这种方法的适当描述的话,对不起。
干杯&hth。,
没有什么大的理由,除了是偏执狂或通过代码,它是一个布尔大喊大叫。
对于编译器来说,它不会有所作为。
我从来不喜欢这种转换为bool
数据types的技术 – 它的味道是错误的!
相反,我们在这里使用了一个名为boolean_cast
的方便模板。 这是一个灵活的解决scheme,它在做什么更明确,可以使用如下:
bool IsWindow = boolean_cast< bool >(::IsWindow(hWnd));