显示优化的结构

时间:2011-06-22 07:49:40

标签: c

#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;
}

这里我想在tft_op中存储3位,1位e_bit,在no_of_pkt中存储4位,但是我想将o / p作为组合1字节,即希望o / p为FA但是o / pi得到的是0x8我该怎么做才能将o / p作为FA

3 个答案:

答案 0 :(得分:3)

通常,位域在C中定义不明确,如果可能应该避免。由于内存填充,字节序等等,很难说这些位如何在内存中对齐。但要解决您的代码的一些细节:

首先,您必须将结构成员更改为unsigned charunsigned int,否则您将松散一位来表示符号。 tft_op - 成员只有三位宽,但您尝试分配一个需要4位的值(0x8 = 0b1000)。最终在内存中分配了三个零(无论如何,在这台机器上,这又取决于字节序等)。它成功地将e_bit设置为1. no_of_pkttft_op具有相同的问题,0x10(= 0b10000)需要5位,但该字段仅为4位宽。因此,该成员被分配为零。最后,您的位字段如下所示:000:1:000000010000x8

答案 1 :(得分:1)

您的值对于分配的空间来说太大了:

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位(最重要)但是标准(据我所知)并没有指定位应该从哪里开始(它可能是bit0,最少)看看你的输出我想第一个字段是最不重要的位,所以你有:

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;

答案 2 :(得分:0)

st_octet.tft_op = 0x8; //超出范围,最大值为7

st_octet.no_of_pkt = 0x10; //超出范围,max为0xF

程序正确,值不正确。