Detailed introduction to the bit field (bit segment) of C language

I. Introduction

In information processing, when some information is stored, it does not need to occupy a complete byte, but only needs to occupy one or several bits. For example, when storing a switch value, there are only two states of 0 and 1, and a binary bit is sufficient. In order to save storage space and make processing easier, C language provides a data structure called "bit field" or "bit field".
The so-called "bit field" is to divide the bits in a byte into several different areas, and describe the number of bits in each area. Each domain has a domain name, allowing operations by domain name in the program. In this way, several different objects can be represented by a binary bit field of one byte. A bit field is essentially a structure type, but its members are allocated by binary bits.

Two, the bit field

1. Definition of bit fields Bit
fields are defined by structures. Compared with ordinary structures, the members of bit fields need to clearly mark the length of the bits they occupy.
The basic syntax of a bitfield definition is as follows:

struct 位域结构体名 
{
    
    
	位域列表 
};

where the list of bit fields is of the form:

     类型说明符  位域名 : 位域长度;

For example:

 struct BitField
{
    
    
	char a:8;
	char b:2;
	char c:5;
}; 

The structure defines bit fields (bit segments), bit field a occupies 8 bits, bit field b occupies 2 bits, and bit field c occupies 5 bits.
The total length of the bit field is related to the type defined by the field variable, which is a multiple of the length of the storage unit type.
2. Definition of bit field variables
The description of bit field variables is the same as that of structure variables. There are three ways to define first and then explain, to define and explain at the same time, and to explain directly.
For example:

struct BitField
{
    
    
	char a:8;
	char b:2;
	char c:5;
}weiyu; 

Weiyu is a BitField variable, occupying two bytes in total.
3. Precautions for bit fields
1) A bit field must be stored in the same storage unit, and cannot span two storage units.
2) When the remaining space of a storage unit is not enough to store another bit field, the bit field should be stored from the next unit. It is also possible to intentionally make a bit field start from the next unit. For example:

struct bf
{
    
    
	unsigned char a:4;
	unsigned char :0; /*空域*/
	unsigned char b:4; /*从下一单元开始存放*/
	unsigned char c:4;
};

In this bit field definition, a occupies 4 bits of the first byte, the last 4 bits are filled with 0 to indicate not used, b starts from the second byte and occupies 4 bits, and c occupies 4 bits.

struct bf
{
    
    
	 unsigned  char a:5;
	 unsigned  char b:2; 
	 unsigned  char c:4;
};
sizeof(struct bf) =  2 //该位域总长度为2个字节

3) The bit field can have no bit field, then it is only used for filling or adjusting the position. Unnamed bit fields cannot be used. For example:

struct k
{
    
    
  int a:1;
  int :2; /*该2位不能使用*/
  int b:3;
  int c:2;
}; 

4) In the bit field list, try not to have different types of fields, otherwise, the lengths of the bit fields obtained under different compilers will be inconsistent.
4. The use of bit fields
The use of bit fields is the same as that of structure members, and its general form is:

 位域变量名·位域名

Bit fields allow output in various formats.
5. The storage mode of the bit field in the memory
The storage order of different chips is different. For the Intel chip, it is stored from the low bit, but for the Motolola chip, it is just the opposite. Therefore, when using data stored in bit fields for data transmission between different chips, it is necessary to know whether it is data transmission between the same chips, because at the receiving end of the information, it is necessary to ensure that the corresponding bit fields are read in the correct order. , otherwise unpredictable errors will occur! ! !

Three, bit field example

Demo1 : Assign a value to a certain bit field, then perform different assignments or bit operations on the bit field, and output the bit field to the screen respectively.
1) Reference code

#include"stdio.h"
struct bf
{
    
    
	unsigned char a:1;
	unsigned char b:3;
	unsigned char c:3;
};
int main()
{
    
    
	bf bit, *pbit;
	bit.a = 1;
	bit.b = 7;
	bit.c = 2;
	printf(" %d,%d,%d\n",bit.a,bit.b,bit.c);
	pbit = &bit;
	pbit->a = 0;
	pbit->b &= 0x5;
	pbit->c |= 0x5;
	printf(" %d,%d,%d\n",pbit->a,pbit->b,pbit->c);
	printf( " length of bitfield : %d", sizeof( bf ) );
return 0;
}

2) After assigning a value to the bit field for the first time, the state of the memory

insert image description here
Bit 0 stores bit field a, which occupies 1 binary bit, and its value is 1.
Bit 1-3 stores bit field b, which occupies 3 binary bits, and its value is 7. Bit
4-6 stores bit field c. , occupying 3 binary bits, and its value is 2
3) Running result
insert image description here
Demo2 : Assign a value to the bit field as a whole, and then output each bit field separately
1) Reference code

#include"stdio.h"
struct BF
{
    
    
	unsigned char a:5;
	unsigned char b:2;
	unsigned char c:4;
};
int main()
{
    
    
	BF *val;
	unsigned short aa = 1000;//1111101000
	val = ( struct BF * )&aa;
	printf(" BF.a = %d\n", val->a);
	printf(" BF.b = %d\n", val->b);
	printf(" BF.c = %d\n", val->c);
	return 0;
}

2) Memory status
insert image description here
3) Running results
insert image description here

Guess you like

Origin blog.csdn.net/sunnyoldman001/article/details/127839141