以这种方式将整数转换为布尔值的原因是什么?
bool booleanValue = !!integerValue;
而不仅仅是
bool booleanValue = integerValue;
我所知道的是,在VC++ 7中,后者将导致C4800警告而前者不会.这两者之间还有其他区别吗?
"!!"的问题 成语是它简洁,难以看清,容易误认为是错字,容易丢掉其中一个"!",等等.我把它放在"看起来我们可以用C/C++变得多么可爱"的类别中.
写一下bool isNonZero = (integerValue != 0);
......要清楚.
从历史上看,!!
习惯用于确保你的bool确实包含了一个类似bool
变量中预期的两个值中的一个,因为C和C++没有真正的bool
类型,我们用int
s 伪造它.对于"真实"而言,这不是一个问题bool
.
但是使用!!
是一种有效的文档记录方式(对于编译器和任何未来的代码工作人员而言)是的,你确实打算将其int
转换为bool
.
使用它是因为C语言(以及一些预先标准的C++编译器)没有bool
类型,只是int
.所以int
s被用来表示逻辑值:0
应该是意思false
,其他一切都是true
.该!
运营商正在恢复1
从0
和0
从其他一切.Double !
用于反转那些,它确保值只是0
或1
取决于其逻辑值.
在C++中,由于引入了正确的bool
类型,因此不再需要这样做了.但是,由于C与C++的向后兼容性(大多数情况下),您不能只更新所有遗留源,而且您不应该这样做.但是很多人仍然这样做,原因相同:保持他们的代码向后兼容旧的编译器仍然不理解bool
s.
这是唯一真正的答案.其他答案具有误导性.
因为!integerValue表示integerValue == 0和!! integerValue因此表示integerValue!= 0,一个返回bool的有效表达式.后者是信息丢失的演员.
另一个选项是三元运算符,它似乎生成一行较少的汇编代码(无论如何在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
我知道这不是一个巨大的差异,但我很好奇它,只是认为我会分享我的发现.
bool只能有两个状态,0和1.假设有符号的32位整数,整数可以具有从-2147483648到2147483647的任何状态.一元!如果输入为0,则运算符输出1,如果输入为0以外的任何值,则输出0.所以!0 = 1和!234 = 0.第二个!只需切换输出,使0变为1,1变为0.
所以第一个语句保证booleanValue将被设置为等于0或1而没有其他值,第二个语句不会.