Во-первых, вы не можете получить 0xFF
из 0xFF
после помещения его в 4-битную переменную.0xFF
занимает 8 бит.То же самое для 0x66
.
Что касается реинтерпретации битовых полей как единого целого числа, вы могли бы, в очень непереносимом стиле (есть проблемы с прямым порядком байтов / прямым порядком байтов и возможностьюбиты заполнения) используйте union
.
(Это:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
struct myCoolStuff{
union{
struct {
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
};
uint32_t fullField;
};
};
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233};
int main()
{
printf("My full field is: %" PRIX32 "\n", data.fullField);
}
печатает 1122336F
на моем x86_64.)
Для этого переносимо Вы можете просто взять битовые поля и соединить их вручную:
Это:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
struct myCoolStuff{
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
};
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233};
int main()
{
uint32_t fullfield = data.stuff1 << 28 | data.stuff2 << 24 | data.stuff3;
printf("My full field is: %" PRIX32 "\n", fullfield);
}
должно печатать F6112233
в любом месте, где он компилируется (uint32_t
не гарантированно существует(хотя на платформах POSIX это будет); uint_least32_t
было бы более переносимым.)
Будьте внимательны, чтобы убедиться, что data.stuff1
имеет достаточно битов, чтобы их можно было сдвинуть на 28
.Ваш делает, потому что он набрал uint32_t
, но было бы безопаснее сделать это, например, с (data.stuff1 + 0UL)<<28
или (data.stuff1 + UINT32_C(0))<<28
и то же самое для второй смены.