Вы не должны этого делать. Многие архитектуры предъявляют требования к выравниванию данных. Например, разыменование указателя, не выровненного по границе слова на машине SPARC, приведет к сбою программы с ошибкой шины (SIGBUS
).
Переносимый способ разделения int
на байты - использование побитовых операций (при условии 8-битных байтов):
uint8_t b3 = 0x12, b2 = 0x34, b1 = 0x56, b0 = 0x78;
uint32_t a;
a = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
printf("%08X\r\n", a);
a = 0x89ABCDEF;
b3 = (a >> 24) & 0xFF;
b2 = (a >> 16) & 0xFF;
b1 = (a >> 8) & 0xFF;
b0 = a & 0xFF;
printf("%02X%02X%02X%02X\r\n", b3, b2, b1, b0);
То же самое может быть не переносимым , достигаемым с помощью типа пробивания трюков через union
с, таких как:
typedef union {
uint32_t val;
uint8_t bytes[4];
} DWORD_A;
typedef union {
uint32_t val;
struct {
unsigned b0:8;
unsigned b1:8;
unsigned b2:8;
unsigned b3:8;
};
} DWORD_B;
Однако этот метод приводит к определенному поведению реализации и поэтому не рекомендуется :
- Порядок байтов зависит от порядкового номера хоста.
- Упаковка битовых полей не переносима.
- Добавлена сложность / накладные расходы из-за кода, сгенерированного компилятором для предотвращения неправильного доступа.
- Проблемы с выравниванием в реализациях, которые не мешают им.