为什么这种情况总是如此? (pktNum!= invPktNum)

时间:2010-11-22 23:36:14

标签: c

当我编译以下代码时,我的编译器抱怨以下行始终为true。我想我可能对!=运算符有错误的理解......

if (pktNum != ~invPktNum) {
    return 1;
}

我正在尝试验证invPktNum确实是pktNum的反转。如果没有,立即退出,否则继续正常进行。

我已经检查过pktNum一个0x01的无符号字符,而invPktNum是一个在比较时为0xFE的无符号字符。

任何人都可以开导我吗?提前谢谢!

4 个答案:

答案 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在您的代码中有不同的定义,否则不会显示。