将int(32位)转换为char(8位)
我有这些定义:
int data = uartBaseAddress[UART_DATA_REGISTER / 4]; // data coming from UART RX port char message[20]; // array of 20 chars
现在当我尝试这样做时:
message[0] = (char) data; printf("%x", message[0]);
它打印(例如): "ffffff9c"
。 当然我只想要最后8位(“9c”),我不明白如何正确地进行从int
到char
的转换。
编辑:我的意思是:我必须像这样填充数组:
data = 0xFFFFFF9c; message[0] = data & 0xFF; -- it has to contain only 9c data = 0xFFFFFFde; message[1] = data & 0xFF; -- it has to contain only de etc...
转换是正确的。 这是printf
的问题所在。
显然,在您的系统上签署了简单char
(可以是签名或未签名)。
我打算猜测打印的值是ffffff9c
(8位),而不是ffffffff9c
(10位); 请validation。
data
的价值可能是-100
。 将该值从int
转换为char
将产生-100
,因为该值在char
类型的范围内(可能是-128
.. +127
)。
但是%x
格式说明符需要类型为unsigned int
的参数,而不是int
。 当传递给printf
时, message[0]
值被提升为int
,但是由于格式字符串, printf
假定该参数的类型为unsigned int
。
严格来说,行为是未定义的,但很可能printf
只是将传递给它的int
值视为unsigned int
。 (int)-100
和(unsigned int)0xffffff9c
具有相同的表示forms。
没有printf
格式说明符以hex格式打印有符号值。 如果您将格式从%x
更改为%d
,则至少会看到正确的值。
但你应该退一步决定你想要完成的事情。 如果要提取低8位data
,可以通过屏蔽它来实现,正如unwind的答案所暗示的那样。 或者您可以将其转换为unsigned char
而不是plain char
以保证您将获得无符号值。
当传递给printf
, unsigned char
值仍然被提升为int
,所以要完全正确,你应该显式地将它转换为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]
是一个unsigned char
,因此它将被转换为非负的int
值,并且有一个特殊情况规则,即int
和带有相同值的unsigned int
参数可以作为函数参数互换。 尽管如此,我自己的偏好是使用强制转换,因为它更清晰,并且因为添加强制转换更容易(特别是对于阅读代码的任何人),而不是遵循说没有必要的推理线。
不需要message
,只需屏蔽掉你不想要的位:
printf("%x\n", data & 0xff);
要将32位整数转换为8位数的4元素数组,请执行以下操作:
const uint32_t data = ... uint8_t message[20]; for(int i = 0; i < 4; ++i) { message[i] = data & 0xff; data >>= 8; }
以上使用little-endian字节顺序。 如果data
是0x12345678
,则message
将开始0x78, 0x56, 0x34, 0x12
。