отображение оптимизированной структуры - PullRequest
0 голосов
/ 22 июня 2011
#include <stdio.h>
typedef struct _octet
{
char tft_op:3;
char e_bit:1;
char no_of_pkt:4;
}octet_t;

int main()
{
octet_t st_octet;
st_octet.tft_op = 0x8;
st_octet.e_bit = 0x1;
st_octet.no_of_pkt = 0x10;
char *ptr = (char*)&st_octet;
printf("%#x\n",*ptr);
return 0;
}

здесь я хочу сохранить 3 бита в tft_op, 1 бит e_bit, 4 бита в no_of_pkt, но я хочу, чтобы o / p представлял собой объединенный 1 байт, т.е. 0x8, что я должен сделать, чтобы получить o / p как FA

Ответы [ 3 ]

3 голосов
/ 22 июня 2011

В общем, битовые поля плохо определены в C и их следует избегать, если это возможно. Из-за заполнения памяти, порядка байтов и т. Д. Трудно сказать, как биты будут выровнены в памяти. Но для того, чтобы обратить внимание на некоторые особенности вашего кода:

Прежде всего вы должны изменить элементы структуры на unsigned char или unsigned int, в противном случае вы потеряете один бит для представления знака. Член tft_op имеет ширину всего три бита, но вы пытаетесь присвоить значение, которое требует 4 бита (0x8 = 0b1000). В итоге ему назначаются три нуля в памяти (в любом случае, на этой машине это снова будет зависеть от порядка байтов и т. Д.). Он успешно устанавливает e_bit в 1. У no_of_pkt есть та же проблема, что и для tft_op, 0x10 (= 0b10000) требуется пять битов, но ширина поля составляет всего 4 бита. Следовательно, этому члену назначены нули. В конце ваше битовое поле выглядит так: 000:1:0000, или 0001000, или 0x8.

1 голос
/ 22 июня 2011

Ваши значения слишком велики для выделенного пространства:

0x8 = 1000b - four bits, not three
0x1 = 1b - but if char is signed you can only have 0 and -1!
0x10 = 16 = 10000b - five bits, you'be allocated four

Итак, эффективный результат:

(0x8 | (0x1 << 3) | (0x10 << 4)) & 0xff

=> (0x8 | 0x8 | 0x100) & 0xff

=> 0x8

что ты и получаешь. 0xfa это:

11111010b

но вы предполагаете, что первый элемент в структуре находится в позиции бита 7 (наиболее значимый), но стандарт (насколько я знаю) не указывает, где должны начинаться биты (это может быть бит 0, наименее значительно) и, глядя на ваш вывод, я думаю, что первое поле является наименее значимым битом, поэтому у вас есть:

ccccbaaa

где a - tft_op, b - e_bit, а c - no_of_pkt. Чтобы получить 0xfa это либо:

tft_op = 2
e_bit = 1
no_of_pkt = 15

или, если заказ обратный:

tft_op = 7
e_bit = 1
no_of_pkt = 10

Кроме того, вместо char *ptr = (char*)&st_octet; изучите использование объединения:

typedef union
{
  struct _octet
  {
    char tft_op:3;
    char e_bit:1;
    char no_of_pkt:4;
  };
  char data;
} octet_t;
0 голосов
/ 22 июня 2011

st_octet.tft_op = 0x8;// вне диапазона макс. 7

st_octet.no_of_pkt = 0x10;// вне диапазона, макс 0xF

Программа правильная, значения неправильные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...