HBv*_*Bv6 2 c arrays int type-conversion char
我有这些定义:
int data = uartBaseAddress[UART_DATA_REGISTER / 4]; // data coming from UART RX port
char message[20]; // array of 20 chars
Run Code Online (Sandbox Code Playgroud)
现在当我尝试这样做时:
message[0] = (char) data;
printf("%x", message[0]);
Run Code Online (Sandbox Code Playgroud)
它打印(例如): "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...
Run Code Online (Sandbox Code Playgroud)
不需要message,只需屏蔽您不想要的位:
printf("%x\n", data & 0xff);
Run Code Online (Sandbox Code Playgroud)
要将 32 位整数转换为 8 位数字的 4 元素数组,请执行以下操作:
const uint32_t data = ...
uint8_t message[20];
for(int i = 0; i < 4; ++i)
{
message[i] = data & 0xff;
data >>= 8;
}
Run Code Online (Sandbox Code Playgroud)
以上使用小端字节序。如果data是0x12345678,message则将开始0x78, 0x56, 0x34, 0x12。
转换是正确的.这就是printf问题所在.
显然char在您的系统上签署了plain (可以是签名或未签名).
我打算猜测打印的值是ffffff9c(8位),而不是ffffffff9c(10位); 请验证.
价值data可能是-100.将该值转换int为char将产生-100,因为该值在类型范围内char(可能是-128.. +127).
但%x格式说明符需要类型的参数unsigned int,而不是int.在传递给它时,值message[0]被提升为,但是,由于格式字符串,假定参数是类型.intprintfprintfunsigned int
严格地说,行为是未定义的,但很可能printf只是采用int传递给它的值并将其视为一个unsigned int.(int)-100并(unsigned int)0xffffff9c具有相同的表示.
没有printf格式说明符可以十六进制打印有符号值.如果您将格式更改%x为%d,则至少会看到正确的值.
但你应该退一步决定你想要完成的事情.如果你想提取低阶8位data,你可以通过屏蔽它来实现,正如unwind的答案所暗示的那样.或者您可以将其转换为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]);
Run Code Online (Sandbox Code Playgroud)
严格来说,(unsigned int)没有必要.message[0]是一个unsigned char,所以它将转换为非负值int,并且有一个特殊情况规则,int并且unsigned int具有相同值的参数可以作为函数参数互换.尽管如此,我自己的偏好是使用强制转换,因为它更清晰,并且因为添加强制转换更容易(特别是对于阅读代码的任何人)而不是遵循说没有必要的推理线.