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