Как правильно преобразовать массив без знака char в uint32_t

Итак, я пытаюсь преобразовать массив unsigned char в uint32_t, но каждый раз получаю разные результаты:

unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};;
uint32_t num = (uint32_t*)&buffer;

Теперь я продолжаю получать это предупреждение:

предупреждение: инициализация делает целое число из указателя без литой

Когда я изменяю num на *num, я не получаю это предупреждение, но на самом деле это не настоящая проблема (UPDATE:), теперь это может быть связано с тем, что я думаю об этом.), потому что каждый раз, когда я запускаю код, возникают разные результаты. Во-вторых, num, как только он правильно набрал, должен быть 128, но если мне нужно изменить сущность буфера, я мог бы это сделать сам, я думаю.

Спасибо!

Ответ 1

Вы пробовали это?

num = (uint32_t)buffer[0] << 24 |
      (uint32_t)buffer[1] << 16 |
      (uint32_t)buffer[2] << 8  |
      (uint32_t)buffer[3];

Таким образом вы контролируете сущность и многое другое.

На самом деле небезопасно указывать указатель char и интерпретировать его как нечто большее. Некоторые машины ожидают, что указатели на целые числа будут выровнены.

Ответ 2

Ответ cnicutar является лучшим, если вы хотите получить определенную фиксированную контенту. Если вы хотите, чтобы host endian, попробуйте:

uint32_t num;
memcpy(&num, buffer, 4);

или примените ntohl к ответу cnicutar. Любой метод, основанный на типе punning, является неправильным и опасным.

Ответ 3

Сначала вы хотите сказать num = *(uint32_t *)&buffer

Чтобы изменить endianness, вы можете использовать вызов типа bswap_32 (в linux, byteswap.h) или OSSwapInt64 (в osx, libkern/OSByteOrder.h)

Ответ 4

Заимствование из @Mr. R. выше, мой подход для преобразования 3-байтного массива без знака без знака char в структуру с небольшим количеством 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);`