C language bit domain and sample code _c language

Source: Internet
Author: User

Some data is stored without the need to occupy a full byte, only one or a few bits is required. For example, the switch is only power and power off two states, with 0 and 1 is sufficient, that is, with a binary. It is based on this consideration that the C language provides a data structure called a bit domain.

When we define a struct, we can specify the number of bits (bit) that a member variable occupies, which is the bit field. Take a look at the following example:

struct bs{
  unsigned m;
  unsigned n:4;
  unsigned char ch:6;
}

: The following numbers are used to qualify the number of bits that a member variable occupies. Member M does not have a limit, it can be inferred that it occupies 4 bytes (byte) of memory based on the data type. Members N, ch are: the number of subsequent digits is limited and no longer can be computed based on the data type, which occupies 4, 6 bit memory respectively.

N, the value of CH is very limited, the data slightly larger will overflow, please see the following example:

#include <stdio.h>
int main () {
  struct bs{
    unsigned m;
    unsigned n:4;
    unsigned char ch:6;
  } A = {0xad, 0xE, ' $ '};
  First output
  printf ("% #x,% #x,%c\n", a.m, A.N, a.ch);
  After changing the value
  , output a.m = 0xb8901c again;
  A.N = 0x2d;
  a.ch = ' Z ';
  printf ("% #x,% #x,%c\n", a.m, A.N, a.ch);
  return 0;
}

Run Result:

0xad, 0xe, $
0xb8901c, 0xd,:

For n and CH, the first output is complete and the second output data is incomplete.

The first time output, the value of N, ch is 0xE, 0x24 (' $ ' corresponding to the ASCII code for 0x24), converted to binary is 1110, 10 0100, no more than the limit of the number of digits, to normal output.

The second output, the value of N, ch into 0x2d, 0x7a (' z ' corresponding to the ASCII code for 0X7A), converted to binary is 10 1101, 111 1010, are beyond the qualified number of digits. The excess part is directly truncated, leaving 1101, 11 1010, converted into 16 in 0xd, 0x3a (0x3a corresponding character is:).

The C language standard stipulates that the width of a bit field cannot exceed the length of the data type it is attached to. In layman's terms, member variables are of type, and this type restricts the maximum length of a member variable: The following number cannot exceed this length.

For example, the above bs,n type is unsigned int, length is 4 bytes, total 32 bits, then the number after n can not exceed 32;ch type is unsigned char, length is 1 bytes, total 8 digits, then the number of CH can not exceed 8.

We can say that bit-domain technology is to store the data by selecting a part of the bit width in the memory occupied by the member variable.

The C language standard also stipulates that only a limited number of data types can be used for bit fields. In ANSI C, these data types are int, signed int, and unsigned int (int is the signed int by default); C99,_bool was also supported.

On the C language standard and the difference between ANSI C and C99, we have in the VIP tutorial "C language of the two sets of standards," explained.

The compiler, however, expanded in concrete implementations, with additional support for Char, signed char, unsigned char, and enum types, so the code above

does not conform to the C language standard, but it can still be supported by the compiler.

Storage of bit fields

C language standard does not specify the location of the specific storage mode, different compilers have different implementations, but they all try to compress storage space.

The specific storage rules for bit fields are as follows:

1 when the type of adjacent member is the same, if their bit width is less than the sizeof size of the type, then the members next to the previous member are stored until they cannot be accommodated, and if their bit width is greater than the type's sizeof size, then the subsequent members will start with the new storage cell. The offset is an integer multiple of the type size.

Take the following bit-field BS as an example:

#include <stdio.h>
int main () {
  struct bs{
    unsigned m:6;
    unsigned n:12;
    unsigned p:4;
  };
  printf ("%d\n", sizeof (struct BS));
  return 0;
}

Run Result:

4

The types of M, N, p are all unsigned int,sizeof The result is 4 bytes (byte), or 32 bits (bit). M, N, p's bit widths are 6+12+4 = 22, less than 32, so they are stored next to each other, with no gaps in between.

The size of the sizeof (struct BS) is 4, not 3, because the memory is aligned to 4 bytes in order to improve access efficiency, which is explained in more detail in the section "C Language memory alignment, increased addressing efficiency," in the "C Language and Memory" topic.

If you change the bit width of member M to 22, the output will be 8, because 22+12 = 34, greater than the 32,n will be stored from the new location, and the offset of M is sizeof (unsigned int), or 4 bytes.

If you change the bit width of member p to 22, the output will be 12, and three members will not be stored next to each other.

2 when the types of adjacent members are different, the compiler has different implementations, GCC compresses the storage, and Vc/vs does not.

Take a look at the bit field BS below:

#include <stdio.h>
int main () {
  struct bs{
    unsigned m:12;
    unsigned char ch:4;
    unsigned p:4;
  };
  printf ("%d\n", sizeof (struct BS));
  return 0;
}

Under GCC, the results are 4, three members are stored next to each other, and the results under Vc/vs are 12, and three members are stored according to their type (as stored in the same way that they do not refer to the position width).

The length of M, CH, p is 4, 1, 4 byte respectively, total occupies 9 bytes of memory, why is the output under Vc/vs is 12? This question will be solved for you in the C language and memory topic, "C language memory alignment, improve addressing efficiency" section.

3 If a member is interspersed between members, it is not compressed. For example, for the following BS:

struct bs{
  unsigned m:12;
  unsigned ch;
  unsigned p:4;
};

The results of sizeof under each compiler are 12.

Through the above analysis, we found that the bit domain members often do not occupy the full byte, and sometimes not at the beginning of the byte, so it is meaningless to use & to obtain the address of the bit-domain member, and the C language is forbidden to do so. The address is the number of bytes (byte), not the number of bits (bit).
No Fame fields

A bit-domain member can have no name, give only the data type and the bit width, as follows:

struct bs{
  int m:12;
  int:20; The bit domain member cannot use
  int n:4;

No fame fields are generally used to fill or adjust member positions. No fame domain is not available because there is no name.

In the example above, if there are no unnamed members with a bit width of 20, M and N will be stored next to each other, the result of sizeof (struct BS) is 4; With these 20 bits as fill, M, n will be stored separately, sizeof (struct BS) result is 8.

The above is the C language bit field of data collation, follow-up continue to supplement the relevant information, thank you for your support of this site!

Related Article

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.