位屏蔽(char)(0xFFFFFFB8&;0xFF)不';我不能在c工作
我正在努力进行位屏蔽或处理位溢出 我从数据流中获取数据,它存储在位屏蔽(char)(0xFFFFFFB8&;0xFF)不';我不能在c工作,c,bit-manipulation,C,Bit Manipulation,我正在努力进行位屏蔽或处理位溢出 我从数据流中获取数据,它存储在chartype缓冲区中,我需要访问缓冲区的特定索引。当我尝试这样做时,我得到了意想不到的结果 下面是一个例子 char buffer[BUFFER_SIZE]; /* ...recv from network stream performed... */ printf("buffer[index] = 0x%x\n", buffer[index]); /* => 0xFFFFFFB8 */ char dummyChar
char
type缓冲区中,我需要访问缓冲区的特定索引。当我尝试这样做时,我得到了意想不到的结果
下面是一个例子
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
类型。为什么打印缓冲区[索引]时会得到32位大小
我还用0x000000FF屏蔽了缓冲区[index]
,但仍然得到0xffffb8。为什么?
我只想得到0xB8,有人能告诉我怎么做吗?我很确定它是1字节大小。有两个原因:第一个原因是,当传递小于
int
的整数类型时,它会自动升级为int
(这可能是符号扩展值)。第二个原因是因为格式%x”
用于打印无符号int
值,而不是字节
对于无符号字节(无符号字符
),应使用修饰符hh
,如“%hhx”
。然后将知道传递的值实际上是单个无符号字节,而不是完整的无符号int
有关更多详细信息,请参阅上面的链接参考。您试图屏蔽的字符,
buffer[index]
的值为负值-72,因为类型char已在您的计算机上签名。它的十六进制表示法是0xB8
将参数buffer[index]
传递给printf函数时,将对其执行整数提升。这意味着its类型(即char)将升级为int类型。在您的计算机上,int类型中的-72表示形式与char类型中的-72表示形式不同:
在char类型中,-72表示为0xB8
在int类型中,-72表示为0xFFFFB8
执行and位操作不会更改值:
char dummyChar = buffer[index] & 0x000000FF;
因为1:0xFF&0xB8==0xB8。字符dummyChar
将具有相同的值-72。然后将dummyChar
传递给printf调用,并执行与上述相同的升级过程
1实际情况略有不同,因为整数提升也会发生在按位运算符上,但结果是相同的。这两种类型都升级为int,然后执行按位and,然后将结果隐式转换为char:
0xFFFFFFB8 & 0x000000B8 == 0x000000B8
0x000000B8 == 0xB8
保持值与操作前相同。使用
无符号字符
而不是裸字符
。谢谢。现在可以了!:)更好的是,在进行这种编程时,在任何地方都使用stdint.h类型。如果需要8位,请使用uint8\t
char
不能保证有8位(如果有,则标准保证有uint8\u t
),因为Olaf已经编写,您应该使用uint8\u t
,并使用printf(“0x%”PRIx8“\n”,buffer[index])
来打印它(包括使用它)。参见C99草案n1256:7.8.1我尝试了你的建议,但没有成功。并不是所有的缓冲区索引都打印0xFFFFFF。某些字节以正确的方式打印。而且,当我铸造(int)(buffer[index]&0x000000FF)时,它给了我0xB8…你的链接说%x
需要无符号的int
,而不是int
。将%x
与一个有争议的负值一起使用是未定义的行为。我想我会同意,但这不是这个问题的主题。@M.M,不,不是,这是完美定义的行为-72
被转换为整数-72
,-72
在十六进制中是0xFFFFFFB8
@LuisColorado如果你错了,标准明确规定%x
必须提供一个无符号int
参数。这些评论不是进行长时间讨论的地方。关于相关的讨论嗯,恐怕在男人们区分有符号和无符号的int
s之前,%x
就已经出现在场景中了。您引用的引用比第一次出现的%x
格式更新,很遗憾必须遵守旧的行为(定义或未定义)。