вопрос о структуре и указателях - PullRequest
0 голосов
/ 27 сентября 2010

давайте рассмотрим следующий код

#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct bf_{
    unsigned x:4;
    unsigned y:4;
    unsigned z:4;
    unsigned  w:4;
    }bf;
int main(){
    unsigned short i=8;
    unsigned short j=9;
    bf* bitfields=(bf *)&i;
    bf*bit=(bf*)&j;
    bitfields->w=12;
    printf("%d\n",bitfields->x);
    printf("%d\n",bit->y);
    printf("%d\n",bitfields->w);



     return 0;
}

этот фрагмент

unsigned short j=9;
bf*bit=(bf*)&j;
printf("%d\n",bit->y);

Я добавил после догадки некоторую интересную характеристику этого кода, например, после этого места

bf* bitfields=(bf *)&i;

когда мы пишем printf("%d\n",bitfields->x);, который печатает 8, я понимаю, что с помощью указателей и ссылок значение i будет предоставлено x, и поэтому оно печатает 8, например, когда мы пишем bitfiled->y, оно пишет 0, поэтому я решил ввести второй элементпеременная j создает новый экземпляр структуры bf и делает ссылку на j, после чего выражение bit-> y должно написать 9, потому что, как я понимаю, это определение порядка, но оно дает мне 0 почему?Пожалуйста, объясните мне, как работает этот код? Я не говорящий по-английски, поэтому, пожалуйста, извините за мой плохой английский

Ответы [ 2 ]

3 голосов
/ 27 сентября 2010

Прежде всего, в этом коде отсутствуют ссылки. Символ &, когда используется как унарный оператор (а не как часть имени типа), как в этом контексте, означает «адрес-из». Таким образом, &i является "адресом i", не"ссылкой на i".

Я не уверен, откуда вы взяли, что использование значения 9 в качестве структуры bf должно заставить y получить значение 9. Когда вы пишете это:

bf* bitfields=(bf *)&i;

В результате вы говорите компилятору «обрабатывать значение в ячейке памяти &i, как если бы оно было bf структурой». Структура bf определена таким образом, что, начиная с младших значащих (самых правых) битов, первые четыре бита являются значением x, вторые четыре бита являются значением y, третьи четыре бита являются значением z значение и т. Д.

Так как значение в местоположении &i равно 8, а 8 в 16-битном двоичном виде равно

0000 0000 0000 1000 

Поля bitfields будут:

0000 0000 0000 1000 
  w    z    y    x

Таким образом, значение x (4-разрядное целое число без знака) равно 8, а значения y, z и w равны 0.

В случае, если вы пишете

bf*bit=(bf*)&j;

вы делаете то же самое, что и выше, за исключением того, что теперь значение равно 9, поэтому назначения:

0000 0000 0000 1001 
  w    z    y    x

Итак, x имеет значение 9, а остальные значения по-прежнему равны 0.

Если вы хотите присвоить значение 9 для y вместо x, назначения должны выглядеть следующим образом:

0000 0000 1001 0000 
  w    z    y    x

Таким образом, вам нужно использовать значение с 16-битным двоичным представлением

0000 0000 1001 0000 

То есть 144. Так что если вы позволите j = 144 вместо j = 9, вы заметите, что bit->y равно 9, а все остальные поля в bit равны 0.

0 голосов
/ 27 сентября 2010

Я думаю, это из-за упаковки, которая происходит при компиляции структуры или класса. Смотрите эти ссылки:

http://msdn.microsoft.com/en-us/library/83ythb65.aspx#vclrfhowalignworkswithdatapacking.
http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx

По умолчанию размер структуры во время компиляции равен , а не , как общий размер ее членов.

...