我正在努力进行位屏蔽或处理位溢出。
我从数据流中获取数据,并将其存储在char
类型缓冲区中,我需要访问缓冲区的特定索引。当我这样做时,我会得到意想不到的结果。
下面的东西..
char buffer[BUFFER_SIZE];
/* ...recv from network stream performed... */
printf("buffer[index] = 0x%x\n", buffer[index]); /* => 0xFFFFFFB8 */
char dummyChar = buffer[index] & 0x000000FF;
printf("dummyChar = 0x%x\n", dummyChar); /* => 0xFFFFFFB8 */
缓冲区为char
类型。为什么在打印缓冲区[index]时我得到32位大小?
我还用0x000000FF掩盖了buffer[index]
,但我仍然得到0xFFFFFFB8。为什么呢?
我只想得到0xB8,谁能告诉我怎么样?我很确定它是1字节大小..
答案 0 :(得分:4)
有两个原因:第一个原因是,当传递小于int
的整数类型时,它会自动提升为int
(可能会对值进行符号扩展)。第二个原因是因为printf
格式"%x"
用于打印unsigned int
值,而不是字节。
对于 无符号 字节(unsigned char
),您应该使用hh
中的修饰符"%hhx"
。然后printf
将知道传递的值实际上是一个无符号字节,而不是一个完整的unsigned int
。
有关详细信息,请参阅上述链接参考。
答案 1 :(得分:2)
您尝试屏蔽的字符buffer[index]
的负值为-72,因为您的计算机上已签署char类型。它的十六进制表示是0xB8。
当参数buffer[index]
传递给printf函数时,会对其执行整数提升。这意味着它的类型是char,它被提升为int类型。 int类型中-72的表示形式与机器上char类型中-72的表示形式不同:
在char类型中,-72表示为0xB8。
在int类型中,-72表示为0xFFFFFFB8
执行和按位操作不会更改值:
char dummyChar = buffer[index] & 0x000000FF;
因为 1 :0xFF& 0xB8 == 0xB8。字符dummyChar
将具有相同的-72值。然后dummyChar
被传递给printf调用,并且如上所述发生相同的促销过程。
1 由于按位运算符也会发生整数提升,但实际情况略有不同,但结果是相同的。两种类型都被提升为int,然后是bitwise并执行,然后结果被隐式转换为char:
0xFFFFFFB8 & 0x000000B8 == 0x000000B8
0x000000B8 == 0xB8
保留该值与操作前相同。