So, I'm trying to convert an array of unsigned char
s into an uint32_t
, bu开发者_StackOverflowt keep getting different results each time:
unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};;
uint32_t num = (uint32_t*)&buffer;
Now, I keep getting this warning:
warning: initialization makes integer from pointer without a cast
When I change num
to *num
i don't get that warning, but that's not actually the real problem (UPDATE: well, those might be related now that I think of it.), because every time I run the code there is different results. Secondly the num
, once it's cast properly, should be 128
, but If I need to change the endianness of the buffer I could manage to do that myself, I think.
Thanks!
Did you try this ?
num = (uint32_t)buffer[0] << 24 |
(uint32_t)buffer[1] << 16 |
(uint32_t)buffer[2] << 8 |
(uint32_t)buffer[3];
This way you control endianness and whatnot.
It's really not safe to cast a char
pointer and interpret it as anything bigger. Some machines expect pointers to integers to be aligned.
cnicutar's answer is the best assuming you want a particular fixed endianness. If you want host endian, try:
uint32_t num;
memcpy(&num, buffer, 4);
or apply ntohl
to cnicutar's answer. Any method based on type punning is wrong and dangerous.
First, you want to say num = *(uint32_t *)&buffer
To change endianness, you can use a call like bswap_32 (in linux, byteswap.h) or OSSwapInt64 (in osx, libkern/OSByteOrder.h)
The warning was issued because &buffer
yields a pointer to pointer. Even without the reference operator &
the warning wouldn't have disappeared because the casting changes only the pointer type. The pointer is further converted to integer and therefore the warning.
If endianness is not important, the obvious solution seems to me
unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};
uint32_t num = *(uint32_t *)buffer;
which means dereferencing the casted pointer to the char array.
Borrowing from @Mr. R. above, my approach for converting a 3 byte big endian unsigned char array within a structure to a little endian unsigned int...
struct mystruct {
int stuff;
int stuff2;
unsigned char x[3] // big endian
}
mystruct z;
unsigned int y // little endian
memcpy(&y, z->x, 3);
y=be32toh(y<<8);`
Assuming it's the same endianess a union would the best option.
union
{
uint32_t u32;
float flt;
uin8_T bytes[4];
} converter;
// Use of the above union
converter.bytes = your_byte_array;
uint32_t u32_output = converter.u32;
float float_output = converter.flt;
精彩评论