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

Jus*_*tin 6 c

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

if (pktNum != ~invPktNum) {
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

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

我已经检查过pktNum一个无符号的字符,它是0x01,并且invPktNum是比较时为0xFE的无符号字符.

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

caf*_*caf 10

在C中,大多数表达式中比较窄的类型的值在int计算发生之前被提升为更宽的类型.如果int宽度足以容纳较窄类型的所有值,则将其提升为int; 否则它被提升为unsigned int.

在这种情况下,int宽度足以容纳您的所有值unsigned char,因此您的值将被提升为int.

pktNum(因此,提升的pktNum)可以具有0到255之间的值(包括0和255).这是将在!=操作员左侧使用的值.

invPktNum同样可以具有0到255之间的值,包括0和255.此值将被提升为int,然后按位取反.这种按位否定的结果将始终为负数,因为符号位将被否定.这是将在!=操作员右侧使用的值.

没有负数可以等于晋升pktNum,所以条件总是如此.

要执行您真正想要的计算,您需要在否定后屏蔽低8位:

if (pktNum != (~invPktNum & 0xff)) {
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以忽略您感兴趣的位:

if (pktNum != (invPktNum ^ 0xff)) {
    return 1;
}
Run Code Online (Sandbox Code Playgroud)