转换是正确的。这是printf
那就是问题所在。
看似平淡char
在您的系统上已签名(可以是已签名的也可以是未签名的)。
我猜打印的值是ffffff9c
(8 位数字),不是ffffffff9c
(10 位数字);请核实。
的价值data
可能是-100
。将该值转换为int
to char
会产生-100
,因为该值在类型范围内char
(大概-128
.. +127
).
But the %x
格式说明符需要类型参数unsigned int
, not int
。的价值message[0]
被提升为int
当它传递到printf
, but printf
,由于格式字符串的原因,assumes参数的类型unsigned int
.
严格来说,该行为是未定义的,但很可能是printf
将简单地采取int
传递给它的值并将其视为一个unsigned int
. (int)-100
and (unsigned int)0xffffff9c
具有相同的表示。
没有printf
格式说明符以十六进制打印有符号值。如果您将格式更改为%x
to %d
,您至少会看到正确的值。
但你应该退后一步,决定你想要实现的目标。如果要提取低8位data
,你可以通过屏蔽它来做到这一点,因为放松的答案 https://stackoverflow.com/a/24040814/827263建议。或者你可以将其转换为unsigned char
而不是简单的char
以保证您会得到一个无符号值。
An unsigned char
值仍提升为int
当传递给printf
,因此为了完全正确,您应该将其显式转换为unsigned int
:
int data = ...;
unsigned char message[20]; // change to unsigned char
message[0] = data; // no cast needed, the value is implicitly converted
printf("%x", (unsigned int)message[0]);
严格来说,(unsigned int)
没有必要。message[0]
is an unsigned char
,所以它会被转换为非负数int
值,并且有一个特殊情况规则说int
and unsigned int
具有相同值的参数可以与函数参数互换。尽管如此,我自己还是倾向于使用强制转换,因为它更清晰,而且添加强制转换比遵循不必要的推理更容易(特别是对于阅读代码的人来说)。