将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”),我不明白如何正确地进行从intchar的转换。

编辑:我的意思是:我必须像这样填充数组:

 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以保证您将获得无符号值。

当传递给printfunsigned 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字节顺序。 如果data0x12345678 ,则message将开始0x78, 0x56, 0x34, 0x12