当我编译以下代码时,我的编译器抱怨以下行始终为true。我想我可能对!=
运算符有错误的理解......
if (pktNum != ~invPktNum) {
return 1;
}
我正在尝试验证invPktNum确实是pktNum的反转。如果没有,立即退出,否则继续正常进行。
我已经检查过pktNum
一个0x01的无符号字符,而invPktNum
是一个在比较时为0xFE的无符号字符。
任何人都可以开导我吗?提前谢谢!
答案 0 :(得分:10)
在C中,大多数表达式中比int
更窄的值的值在计算发生之前被提升为更宽的类型。如果int
的宽度足以容纳较窄类型的所有值,则会将其提升为int
;否则会被提升为unsigned int
。
在这种情况下,int
的宽度足以容纳unsigned char
的所有值,因此您的值会提升为int
。
pktNum
(因此,提升的pktNum
)可以包含0到255之间的值。这是将在!=
运算符的左侧使用的值。
invPktNum
同样可以包含0到255之间的值。此值将提升为int
,然后按位取反。这种按位否定的结果将始终是负数字,因为符号位将被否定。这是将在!=
运算符的右侧使用的值。
任何负数都不能等于提升的pktNum
,因此条件始终为真。
要执行您真正想要的计算,您需要在否定后屏蔽低8位:
if (pktNum != (~invPktNum & 0xff)) {
return 1;
}
或者,您可以忽略您感兴趣的位:
if (pktNum != (invPktNum ^ 0xff)) {
return 1;
}
答案 1 :(得分:0)
您正在查看8位值。我敢打赌,pktNum和invPktNum是32位值,所以你要比较0x000000fe和0xfffffffe。
答案 2 :(得分:0)
也许简单的类型独立测试是:
if (0 == (pktNum & pkNum)) {
等于:
if (0 == (0xfe & 0x01)) {
使用http://codepad.org/nziOGYJG快速测试似乎可以使用多个有符号和无符号long / int类型。
出于兴趣,任何人都有任何意见吗?
答案 3 :(得分:-1)
假设如下:
invPktNum = ~pktNum
然后你的比较相当于:
if (pktNum != ~(~pktNum)) {
或
if (pktNum != pktNum) {
总是假的。除非invPktNum在您的代码中有不同的定义,否则不会显示。