Как работает это взаимодействие и битовое поле? - PullRequest
1 голос
/ 16 апреля 2020

Итак, вот пример:

struct field
{
    unsigned int a : 8;
    unsigned int b : 8;
    unsigned int c : 8;
    unsigned int d : 8;
};

union test
{
    unsigned int raw;
    field bits;
};

int main()
{

    test aUnion;
    aUnion.raw = 0xabcdef;

    printf("a: %x \n", aUnion.bits.a);
    printf("b: %x \n", aUnion.bits.b);
    printf("c: %x \n", aUnion.bits.c);
    printf("d: %x \n", aUnion.bits.d);


    return 0;
}

теперь, когда я запускаю это, я получаю:

a: ef
b: cd
c: ab
d: 0

И я думаю, я просто не понимаю, что здесь происходит. Итак, я установил raw в значение, и, поскольку это объединение, все остальное вытекает из этого, поскольку все они были установлены меньше, чем unsigned int? так битовое поле основано на сырье? но как это на карте? почему в данном случае d: 0?

Буду признателен за любую помощь.

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Использование шестнадцатеричного представления целого числа полезно, потому что оно проясняет, каково значение каждого байта целого числа. Таким образом, установка

aUnion.raw = 0xabcdef;

означает, что значение младшего байта равно 0xef, что второй младший байт имеет значение 0xcd и так далее. Но вы устанавливаете raw поле union , которое является целым числом, поэтому оно имеет длину 4 байта. В предыдущем представлении наиболее значимый байт отсутствует, поэтому его можно записать как

aUnion.raw = 0x00abcdef;

(это все равно, что сделать явным, что целое число x = 42 имеет 0 сотни, 0 тысячи и т. Д. on).

Ваши поля объединения представляют соответственно a =byte[0], b = byte[1], c = byte[2] и d = byte[3] целого числа raw, так как в объединении все элементы совместно используют одну и ту же память место . Это верно, потому что вы выполняете свой код в архитектуре с прямым порядком байтов (сначала идут младшие значащие байты).

Итак:

a = byte[0] of raw = 0xef
b = byte[1] of raw = 0xcd
c = byte[2] of raw = 0xab
d = byte[3] of raw = 0x00
2 голосов
/ 16 апреля 2020

Это потому, что ваш unsigned int недостаточно 32-битный (все 32 бита не установлены), чтобы полностью заполнить все значения битовых полей. Поскольку длина всего 24 бита, битовое поле d показывает шестнадцатеричное значение 00. Попробуйте, например,

aUnion.raw = 0xffabcdef;

, что приведет к

a: ef 
b: cd 
c: ab 
d: ff

Поскольку поле битов dd занимает биты 24-32 (в младшем порядке), если только назначенное поле unsigned int было присвоено значение, которое занимает эти установленные биты, в этом положении битового поля тоже значение не отображается.

...