Как правильно преобразовать массив без знака в uint32_t
Итак, я пытаюсь преобразовать массив unsigned char
в uint32_t
, но продолжайте получать разные результаты каждый раз:
unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};;
uint32_t num = (uint32_t*)&buffer;
Теперь я продолжаю получать это предупреждение:
предупреждение: инициализация делает целое число из указателя без приведения
Когда я меняюсь num
в *num
я не получаю это предупреждение, но на самом деле это не настоящая проблема (ОБНОВЛЕНИЕ: ну, это может быть связано с тем, что я думаю об этом.), потому что каждый раз, когда я запускаю код, появляются разные результаты. Во-вторых num
После того, как он будет правильно сыгран, 128
, но если мне нужно изменить порядок байтов, я смог бы сделать это сам, я думаю.
Спасибо!
4 ответа
Ты пробовал это?
num = (uint32_t)buffer[0] << 24 |
(uint32_t)buffer[1] << 16 |
(uint32_t)buffer[2] << 8 |
(uint32_t)buffer[3];
Таким образом, вы управляете порядком байтов и так далее.
Это действительно не безопасно бросить char
указывать и интерпретировать это как что-нибудь большее. Некоторые машины ожидают, что указатели на целые числа будут выровнены.
Ответ cnicutar - это лучшее предположение, что вы хотите иметь конкретный фиксированный порядок байтов. Если вы хотите, чтобы host endian, попробуйте:
uint32_t num;
memcpy(&num, buffer, 4);
или применить ntohl
к ответу cnicutar. Любой метод, основанный на типе наказания, является неправильным и опасным.
Во-первых, вы хотите сказать num = *(uint32_t *)&buffer
Чтобы изменить порядковый номер, вы можете использовать вызов типа bswap_32 (в linux, byteswap.h) или OSSwapInt64 (в osx, libkern/OSByteOrder.h)
Предупреждение было выпущено, потому что &buffer
дает указатель на указатель. Даже без справочного оператора &
предупреждение не исчезло бы, потому что преобразование изменяет только тип указателя. Указатель далее преобразуется в целое число и, следовательно, в предупреждение.
Если порядок байтов не важен, мне кажется очевидное решение
unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};
uint32_t num = *(uint32_t *)buffer;
что означает разыменование приведенного указателя на массив символов.
Заимствуя из @ R... выше, мой подход к преобразованию 3-байтового массива символов без знака с порядком байтов в структуре к порядковому порядку без знака без знака...
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);`
Предполагая, что это тот же самый порядок байтов, лучшим вариантом будет объединение.
union
{
uint32_t u32;
float flt;
uin8_T bytes[4];
} converter;
// Использование указанного выше союза
converter.bytes = your_byte_array;
uint32_t u32_output = converter.u32;
float float_output = converter.flt;