将int(32位)转换为char(8位)

时间:2014-06-04 14:53:00

标签: c arrays char int type-conversion

我有这些定义:

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...

2 个答案:

答案 0 :(得分:5)

转换是正确的。这是printf问题。

显然,您的系统上已签署了char个简单{可以是签名或未签名的。)

我猜测打印的值是ffffff9c(8位数),而不是ffffffff9c(10位数);请验证。

data的值可能是-100。将该值从int转换为char会产生-100,因为该值在char类型的范围内(可能是-128 .. {{1} })。

+127格式说明符需要%x类型的参数,而不是unsigned int。当int传递给message[0]时,int的值会被提升为printf,但由于格式字符串,printf会被提升为属于unsigned int类型。

严格来说,行为未定义,但很可能printf只会将int值传递给它,并将其视为unsigned int(int)-100(unsigned int)0xffffff9c具有相同的代表性。

没有printf格式说明符以十六进制格式打印有符号值。如果您将格式从%x更改为%d,则至少会看到正确的值。

但你应该退一步决定你想要完成什么。如果要提取data的低8位,可以通过屏蔽它来实现,unwind's answer建议。或者您可以将其转换为unsigned char而非普通char,以保证您获得无符号值。

传递给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]unsigned char,因此它会转换为非负int值,并且有一个特殊情况规则,其中显示intunsigned int具有相同值的参数可作为函数参数互换。尽管如此,我自己的偏好是使用强制转换,因为它更清晰,并且因为添加强制转换更容易(特别是对于阅读代码的任何人),而不是遵循说明没有必要的推理线。

答案 1 :(得分:4)

不需要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