Как правильно преобразовать массив без знака в 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;
Другие вопросы по тегам