displaying the optimised structure
#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开发者_StackOverflow);
return 0;
}
here i want to store 3 bits in tft_op, 1 bit e_bit, 4 bits in no_of_pkt, but i want the o/p as a combined 1 byte i.e is want the o/p as FA but the o/p i get is 0x8 what should i do to get the o/p as FA
In general, bit fields are poorly defined in C and should be avoided if possible. Due to memory padding, endianness etc. it is hard to tell how the bits will be aligned in memory. But to adress some specifics of your code:
First of all you have to change the structure members to unsigned char
or unsigned int
, otherwise you will loose one bit for representing the sign.
The tft_op
-member is only three bits wide, but you try to assign a value which requires 4 bits (0x8 = 0b1000). It ends up being assigned three zeros in memory (on this machine anyway, this again will depend on the endianness etc). It successfully sets the e_bit
to 1. The no_of_pkt
has the same problem as tft_op
, 0x10 (=0b10000) needs five bits, but the field is only 4 bits wide. Hence that member is assigned zeros. In the end your bit field looks like this: 000:1:0000
, or 0001000
, or 0x8
.
Your values are too big for the allocated space:
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
So, the effective result is:
(0x8 | (0x1 << 3) | (0x10 << 4)) & 0xff
=> (0x8 | 0x8 | 0x100) & 0xff
=> 0x8
which is what you're getting. 0xfa is:
11111010b
but you assume that the first item in the structure is at bit position 7 (the most significant) but the standard (as far as I know) doesn't specify where the bits should start (it could be bit0, the least significant) and looking at your output I guess the first field is the least significant bit, so you have:
ccccbaaa
where a is tft_op, b is e_bit and c is no_of_pkt. To get 0xfa it's either:
tft_op = 2
e_bit = 1
no_of_pkt = 15
or, if the order is the other way round:
tft_op = 7
e_bit = 1
no_of_pkt = 10
Also, rather than doing char *ptr = (char*)&st_octet;
look into using a union:
typedef union
{
struct _octet
{
char tft_op:3;
char e_bit:1;
char no_of_pkt:4;
};
char data;
} octet_t;
st_octet.tft_op = 0x8; // out of range, max is 7
st_octet.no_of_pkt = 0x10; // out of range, max is 0xF
The program is correct, values are incorrect.
精彩评论