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

标签 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”),我不明白如何正确地从 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 位数字);请确认。
data的值可能是 -100 .从 int 转换该值至 char将产生 -100 ,因为该值在类型 char 的范围内(可能是 -128 .. +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 value 仍然提升为 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具有相同值的参数可以作为函数参数互换。不过,我个人更喜欢使用强制转换,因为它更清晰,并且因为添加强制转换比遵循没有必要的推理路线更容易(特别是对于阅读代码的任何人)。

关于将 int(32 位)转换为 char(8 位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24040780/

相关文章:

c - 初始化元素在 C 中不是常量

C - Header 中的函数实现是否应该使用 extern/inline/static?

c - 如何在 xterm 中启用日志记录

c - 如何在 Linux 中以编程方式获取目录的大小?

javascript - 在knockout js observableArray中加入函数?

C - 通过网络发送后字符数组更长

Java如何拆分arralyist并设置为单独的字符串或数组

arrays - 已知子集大小且数组为范围的子集求和问题

c++ - 如何检查科学记数法是否为 double C++

java - 在每个元音前添加文本