位屏蔽(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
格式更新,很遗憾必须遵守旧的行为(定义或未定义)。