In-depth analysis of Bit Structure

Source: Internet
Author: User

Keyword: bit structure saves storage space ":" operator Bit Field

I. concepts:

The bitwise structure is a special structure. When you need to access Multiple Digits of one byte or word by bit, the bitwise structure is more convenient than the bitwise operator.
The bit structure is defined as follows:
Struct bit structure name {
Data Type [variable name]: an integer constant. // The member name is a "bit field" or "bit field"
Data Type [variable name]: integer constant;
}-Bit structure variable;
The data type must be an integer (INT/Char/short ). The range of an integer constant is the length of the data type. For example, if it is defined as short, the range is 1 ~ 16.
The variable name is a selection item and can be left unspecified. This is required for arrangement.
For example, a single-digit structure is defined below.
Struct webpage {
Unsigned char Incon: 8;/* Incon occupies a low byte of 0 ~ 8 digits in total */
Unsigned char txcolor: 4;/* txcolor occupies 0 ~ 3 digits, 4 digits in total */
Unsigned char bgcolor: 3;/* bgcolor occupies 4 ~ 6 digits, 3 digits in total */
Unsigned char Blink: 1;/* blink occupies 7th bytes */
} Ch;
Printf ("% d/N", sizeof (struct webpage); output: 2.
The access of the bitwise structure member is the same as that of the structure member.
For example, to access the bgcolor member in the structure of the above sample bit, you can write it as follows:
Ch. bgcolor

Note:
1. A single-bit field must be stored within a data type defined for it and cannot be stored across the data type. For example, if the space remaining for the bit field defined by char is insufficient to store another bit field, the bit field should be stored from the next unit. You can also intentionally start a domain from the next unit.
2. Because the bit field cannot overdefine its data type, the length of the bit field cannot exceed the length of its data type.
3. The total length (number of digits) of the bit structure is the sum of the digits defined by each bit member and then aligned to the largest member.
4. A structure member can be used with other structure members.
For example:
Struct info {
Char name [8];
Int age;
Struct ADDR address;
Float pay;
Unsigned char state: 1;
Unsigned char pay: 1;
} Workers;
The structure of the above example defines information about a worker. There are two bit structure members, each with only one bit structure member, which uses the unsigned char data type. Therefore, only one byte is occupied, but two information is saved, the first digit in this Byte indicates the status of the worker, and the second digit indicates whether the salary has been paid. The bit structure can save storage space.

Ii. Concerning the storage sequence of bit-Domain Structures

We know that the byte storage sequence has a high byte priority big-Endian big-end storage method (high byte data is placed at the low byte address) and low byte priority little-Endian small-end storage method, there is no technical reason for using either the big-end method or the small-end method, but it only involves the standpoint and habits of the processor manufacturer. Intel's X86 platform uses the small-end method. Most of the microprocessors of IBM, Motorola, and Sun Microsystem use the large-end method, and some can be set by users to use the large-end method or small-end method, such as arm, MIPS, and PowerPC.
The storage sequence of bit fields is related to its compiler. Generally, the application is placed at a low level. The program example is as follows:
# Include "stdio. H"
Void main ()
{
Union
{
Struct student
{
Unsigned char S1: 1;
Unsigned char S2: 3;
} X;
Unsigned char C;
} V;
V. C = 0;
V. X. S1 = 0;
V. X. S2 = 4;
Printf ("% d/N", V. C );
Printf ("% d/N", sizeof (struct student ));
}
Output:
8
1

That is, the request for struct members starts from the low address in order. Therefore, the data sorting order of the above struct V in the memory is

S1 S2
| 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | (1 byte, because it is of the unsigned char type)
Low address and high address

S1 0
S2 has 4 (Binary 100) values, and the memory size is from low to high: "| 0 | 0 | 1 | ".
Therefore, V. C is binary 00001000, that is, decimal 8.
At the same time, because S1 occupies one position, S2 occupies three places, and both are unsigned char type, and the largest data type is unsigned char type, one byte is enough to put down S1 and S2. So we can see that the size of struct student is 1 byte.
If the request is placed in the high byte, the output above is
S2 S1
0000 | 001 | 0
That is, the output should be:
64
1
Some people on the Internet say that Turbo C adopts this method. I have never tried it.

Iii. Bit alignment of bit Structures
The bit structure does not actually have the bit alignment problem, that is, the bit does not need to be alignment. In other aspects, the bit structure is similar to the general struct structure and follows the structure alignment principle,

# Include "stdio. H"

Void main ()
{
Union
{
Struct student
{
Unsigned char S1: 1;
Unsigned char S2: 2;
Unsigned char S3: 2;
} X;
Unsigned char C;
} V;
V. C = 0;
V. X. S1 = 0;
V. X. S3 = 2;
Printf ("% d/N", V. C );
Printf ("% d/N", sizeof (struct student ));
}
The output result is:
16
1

Because it only follows the overall alignment
S1s2s3
0 0001000
That is, binary 00010000 equals to decimal 16, instead
S1s2 S3
0 00 0 01 00

Here is an example of a single-digit struct.

# Include "stdio. H"
Void main ()
{
Union
{
Struct student
{
Unsigned char S1: 1;
Unsigned char S2: 2;
Unsigned short S3: 2;
} X;
Unsigned short C;
Unsigned int D;
} V;
V. D = 0;
V. X. S1 = 0;
V. X. S3 = 2;
Printf ("% d/N", V. D );
Printf ("% d/N", sizeof (struct student ));
}
Output:
131072
4

131072 = (10 00000000 00000000) B
S3 skips two bytes because it follows the structure alignment principle.
S1s2 S3
0 00 00000 | 00000000 | 01

For more information about "structure alignment", see repost.
"52rd.com/blog/detail_rd.blog_zjhfqq_7083.html"

All the above programs have passed the c1.7 + xpsp2 + vc6 ++ test.

This article is original. For more information, see the source.
"52rd.com/blog/detail_rd.blog_zjhfqq_7084.html"

Read full text (862) | Reply (1) | reference (0)
Reply: in-depth analysis of Bit Structure
Andrew (traveler) commented on 15:17:00
In the last example, if the alignment is 1 (Pragma pack (1), the output is 512 On the x86 machine. In addition, if the alignment is on the big endian machine, the printed values should be different.

 

 

 

A friend posted the following code:
# Pragma pack (4)
Class testb
{
Public:
Int AA;
Char;
Short B;
Char C;
};
Int nsize = sizeof (testb );
Here, the nsize result is 12, which is expected.

The following code removes the first member variable:
# Pragma pack (4)
Class testc
{
Public:
Char;
Short B;
Char C;
};
Int nsize = sizeof (testc );
According to the normal filling method, the nsize result should be 8. Why does the result show that nsize is 6?

In fact, many people have incorrect understanding of # pragma pack.
# The alignment length specified by the Pragma pack. The actual use rules are as follows:
Structure, union, or data member of the class. The first one is placed in a place with the offset of 0, and the alignment of each data member is later, follow the value specified by # pragma pack and the smaller value in the length of the data member.
That is to say, when the value of # pragma pack is equal to or greater than the length of all data members, the size of this value will not produce any effect.
The overall alignment of the structure is performed based on the smaller value between the largest data member in the structure and the value specified by # pragma pack.

Explanation
# Pragma pack (4)
Class testb
{
Public:
Int AA; // The first member, which is placed at the [] offset,
Char A; // The second member. Its length is 1, # pragma pack (4), with a small value, that is, 1. Therefore, the Member is aligned in one byte, at the offset [4.
Short B; // The Third Member, whose length is 2, # pragma pack (4), takes 2, and is aligned by 2 bytes, so it is placed at the offset [6, 7.
Char C; // fourth, with a length of 1 and placed at the position of [8.
};
The actual memory occupied by this class is 9 bytes.
The alignment between classes is based on the maximum member length within the class and a smaller alignment among the values specified by # pragma pack.
In this example, the alignment length between classes is Min (sizeof (INT), 4), that is, 4.
9 The result of 4-byte rounding is 12, so sizeof (testb) is 12.

If
# Pragma pack (2)
Class testb
{
Public:
Int AA; // The first member, which is placed at the [] offset,
Char A; // The second member. Its length is 1, # pragma pack (4), with a small value, that is, 1. Therefore, the Member is aligned in one byte, at the offset [4.
Short B; // The Third Member, whose length is 2, # pragma pack (4), takes 2, and is aligned by 2 bytes, so it is placed at the offset [6, 7.
Char C; // fourth, with a length of 1 and placed at the position of [8.
};
// It can be seen that the above position is completely unchanged, but the class is changed to 2-byte alignment, and 9 is rounded to 2. The result is 10.
// Therefore, sizeof (testb) is 10.

Finally, check the original post:
The following code removes the first member variable:
# Pragma pack (4)
Class testc
{
Public:
Char A; // The first member, which is placed at the [0] offset,
Short B; // The second member. Its length is 2, # pragma pack (4), take 2, and align it in 2 bytes, so it is placed at the offset [2, 3.
Char C; // The third, with a length of 1 and placed in the position of [4.
};
// The size of the entire class is 5 bytes, alignment by min (sizeof (short), 4) bytes, that is, 2 bytes alignment, and the result is 6
// Therefore, sizeof (testc) is 6.

Thanks Michael raised his question and added:

When _ declspec (align () is displayed in the data definition, the alignment length of the specified type must be compared with its own length with the value specified here, and a large value is obtained. The final class/structure alignment length also needs to be compared with this value, and then take the larger value.

It can be understood in this way, _ Declspec (align () and # pragma pack are brothers. The former specifies the minimum value of alignment, and the latter specifies the maximum value of alignment, the former has a higher priority.
_ Declspec (align () specifies only the Data Alignment position, but does not specify the actual memory length occupied by the data, after the specified data is placed at a specified position, the subsequent data is still filled in the way specified by # pragma pack, the actual size of the class/structure and the memory pattern are as follows:
Before _ declspec (align (), data is filled in the way specified by # pragma pack, as described above. When _ declspec (align () is encountered, first find the alignment point closest to the current offset (the alignment length is max (the data length, the specified value )), then fill the specified data type from this point. The subsequent data type starts after it and is still filled according to # pragma pack, until the next _ declspec (align () is encountered ()).
After all the data is filled, compare the overall alignment value of the structure with the value specified by _ declspec (align (). Take the larger value as the alignment length of the entire structure.
In particular, this parameter does not work when the value specified by _ declspec (align () is smaller than the corresponding type length.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.