Bit field describes the C language

Detailed bit field 1.C language

  • The reason: Some data in the storage does not need to take up a full byte, only need to take one or several binary bit. Switch power on and off, for example, only two states, 0 and 1 is sufficient to use, that is with a binary. It is based on this consideration, C language and provides a data structure called a bit field.
  • When the structure is defined, you can specify a member variable occupied by the number of bits (Bit), this is the bit field. Consider the following example:
        struct bs{
            unsigned m;
            unsigned n: 4;
            unsigned char ch :6;
        }
    
  • Description of Symbols: : number of bits used to define the number after the member variables occupied. M members is not limited, the data type can be deduced that 4 bytes of memory. Members n, ch is: numerical limit the back, can not be calculated according to the length of data types, which are occupied by 4,6-bit memory. n, ch a very limited range, which is slightly larger data overflow occurs, see the following example:
        #include <stdio.h>
    
        int main(){
            struct bs{
                unsigned m;
                unsigned n:4;
                unsigned char ch: 6;
            } a={0xad, 0xE, '$'};
            // 第一次输出
            printf("%#x, %#x, %c\n", a.m, a.n, a.ch);
            // 更改值之后,再次输出
            a.m = 0xb8901c;
            a.n = 0x2d;
            a.ch = 'z';
            printf("%#x, %#x, %c\n", a.m, a.n, a.ch);
            return 0;
        }
    
  • operation result:
        0xad, 0xe, $
        0xb8901c, 0xd, :
    
  • Explanation: and for n ch, first output data is complete, the second output data is incomplete. When first output, the value of n, ch respectively 0xe, 0x24 ( '$' corresponding to the ASCII code is 0x24), is converted into a binary 1110,100100, do not go beyond a defined number of bits, the normal output; second when the secondary output, the value of n, ch becomes 0x2d, 0x7a ( 'z' corresponding to the ASCII code 0x7A), are converted into binary 101101,1111010, are beyond the defined number of bits. Directly excess truncated, leaving 1101,111010, in terms of hexadecimal 0xd, 0x3a (0x3a corresponding characters are :). C language standard, can not exceed the width of the field types of data lengths which it is attached. More simply, member variables are typed, this type limits the maximum length of the member variables: the latter figure should not exceed this length. For example, the above BS, the n type unsigned int, length of 4 bytes, a total of 32, then n can not exceed the latter figure 32; ch of type unsigned char, length of 1 byte, total 8 bit, then the back of the digital ch can not be more than eight. We can believe that technology is a bit field to select a portion of the bit width data stored in the member variables occupied memory. C standard also specifies that only a limited number of data types may be used for bit field. In ANSI C, which is several data types int, signed int and unsigned int (int default is signed int); to C99, _Bool also supported.

2. bitfield storage

  • C language standard does not stipulate specific bit fields of storage, different compilers have different implementations, but they all try to compress storage space. DETAILED bit field storage rule is as follows:
    • (1) when the adjacent members of the same type, if the bit width less than the sum of their type sizeof size, the former member immediately behind a storage member, until it received so far; if their sum is greater than the bit width type when sizeof size, the members of the latter will start a new storage unit, an offset of an integer multiple of the size of the type. In the following bit field bs 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;
          }
      
      • Explain: m, n, p are the type unsigned int, the result is four bytes sizeof (Byte), i.e., 32-bit (Bit). m, n, p, and the bit width is 4 + 6 + 12 = 22, less than 32, they will be stored next, with no gaps. If the bit width m to 22 members, then the output will be 8, since 22 + 12 = 34, greater than 32, n will begin storing the new position, is offset relative to the m sizeof (unsigned int), i.e. four bytes. If p then a member of the bit width was changed to 22, then the output will be 12, three members will not be stored next.
    • (2) when adjacent members are different types, different compilers have different implementations, the GCC will be stored compressed, and the VC / VS not; see the following bit field bs:
          #include <stdio.h>
      
          int main(){
              struct bs{
                  unsigned m:6;
                  unsigned char ch:4;
                  unsigned p: 4;
              };
              printf("%d\n", sizeof(struct bs));
              return 0;
          }
      
      • Explanation: The operation results in the GCC is 4, three members of the stored next; operation results in VC / VS is 12, three members of the respective types of storage (the storage time of the same bit width is not specified).
    • (3) If the bit field is peppered with non-members among members, it will not be compressed. For example, the following bs:
          #include <stdio.h>
      
          int main(){
              struct bs{
                  unsigned m:12;
                  unsigned ch;
                  unsigned p: 4;
              };
              printf("%d\n", sizeof(struct bs));
              return 0;
          }
      
      • He explained: unsigned ch is a non-bit field members, so each compiler results sizeof are under 12.
  • Note: Through the above analysis, we found that bit field members often do not take full byte, sometimes not in the beginning byte position, so using & get bit field members address is meaningless, C language is also prohibited such do. Address byte (Byte) numbers, instead of a bit (Bit) number.

2. unnamed bit field

  • Bit field members may have no name, the data type and the bit width is given only as follows:
        #include <stdio.h>
    
        int main(){
            struct bs{
                unsigned m:12;
                int : 20;
                unsigned n: 4;
            };
            printf("%d\n", sizeof(struct bs));
            return 0;
        }
    
    • Explanation: unknown bit field is generally used as a filler or adjust the position of the members. Because there is no name, unnamed bit field can not be used. In the above example, if the bit width is not unknown members 20, m, n will be stored next, the result sizeof (struct bs) is 4; 20 as a filler with this, m, n will be stored separately, sizeof (struct bs) evaluates to 8.

Reproduced in: https: //www.jianshu.com/p/78aec278b115

Guess you like

Origin blog.csdn.net/weixin_33937913/article/details/91194859