c - 为什么这个条件总是正确的? (pktNum != invPktNum)

标签 c

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

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

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

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

谁能教教我?提前致谢!

最佳答案

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

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

pktNum(因此,提升的 pktNum)的值可以介于 0 和 255 之间(含 0 和 255)。这是将在 != 运算符左侧使用的值。

invPktNum 的值同样可以介于 0 和 255 之间(含 0 和 255)。该值将被提升为 int,然后按位求反。这种按位取反的结果将始终是一个负数,因为符号位将被取反。这是将在 != 运算符右侧使用的值。

没有负数可以等于提升的 pktNum,因此条件始终为真。

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

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

或者,您可以只否定您感兴趣的位:

if (pktNum != (invPktNum ^ 0xff)) {
    return 1;
}

关于c - 为什么这个条件总是正确的? (pktNum != invPktNum),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4251335/

相关文章:

C-从文件中读取行

c - 从openCV中矩阵的所有元素中减去一个值

C - 使用递归创建二叉树时出现段错误

c - 使用 glib 通过 DBus 发送包含数组的结构数组

python - 指针和 "Storing unsafe C derivative of temporary Python reference"

c - 如何将c代码的函数调用树转储到文件中?

c - 如何在codeblock,Windows(初学者)中使用conio.h,dos.h,io.h头文件编译c代码?

用于解析日期时间的 C 库

c - 使用 atoi() 并打印字符串失败 - C

无法在 emacs 中的 gdb 中放置断点