有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。
为了节省存储空间,并使处理简便,C 语言又提供了一种数据结构,称为"位域"或"位段"。
所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。
每个域有一个域名,允许在程序中按域名进行操作。
这样就可以把几个不同的对象用一个字节的二进制位域来表示。
14.1 位域的定义
struct 位域结构名
{
位域列表
};
类型说明符 位域名: 位域长度
例如:
struct bs
{
int a : 8;
int b : 2;
int c : 6;
}data;
说明 data 为 bs 变量,共占两个字节。
其中位域 a 占 8 位,位域 b 占 2 位,位域 c 占 6 位。
14.2 位域说明
对于位域的定义尚有以下几点说明:
一个位域必须存储在同一个字节中,不能跨两个字节。
如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。
也可以有意使某位域从下一单元开始。
struct bs
{
unsigned a : 4;
unsigned : 4; /* 空域 */ /* 该 4 位不能使用 */
unsigned b : 4; /* 从下一单元开始存放 */
unsigned c : 4
}
由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,
另外一些编译器可能会把大于一个域的部分存储在下一个字中。
位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。
位域在本质上就是一种结构类型,不过其成员是按二进位分配的。
14.3 位域的使用
位域变量名·位域名
/*-----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
/*-----------------------------------------------------------------------*/
/* 结构体 */
struct bs
{
unsigned a : 1;
unsigned b : 3;
unsigned c : 4;
} bit, *pbit;
/*-----------------------------------------------------------------------*/
/*
* @brief
* 关于 main 的功能描述:
* 位域的使用.
* @param[in] void
*
* @return return 0
*
* @implements 低层需求标识号 XXXX
*/
int main()
{
bit.a = 1; //给位域赋值(应注意赋值不能超过该位域的允许范围)
bit.b = 7; //给位域赋值(应注意赋值不能超过该位域的允许范围)
bit.c = 15; //给位域赋值(应注意赋值不能超过该位域的允许范围)
printf("%d,%d,%d\n", bit.a, bit.b, bit.c); //以整型量格式输出三个域的内容
pbit = &bit; //把位域变量 bit 的地址送给指针变量 pbit
pbit->a = 0; //用指针方式给位域 a 重新赋值,赋为 0
pbit->b &= 3; //使用了复合的位运算符 "&=",相当于:pbit->b=pbit->b&3
//位域 b 中原有值为 7,与 3 作按位与运算的结果为 3(111&011=011,十进制值为 3)
pbit->c |= 1; //使用了复合位运算符"|=",相当于:pbit->c=pbit->c|1,其结果为 15
printf("%d,%d,%d\n", pbit->a, pbit->b, pbit->c); //用指针方式输出了这三个域的值
/*-----------------------*/
return 0;
}
/*-----------------------------------------------------------------------*/
Visual Studio 运行结果:
非常感谢您的支持!创作不易,转发备注出处!
自用展示内容,不定期更新维护内容,让我们把 C开发 变得更专业。
十年开发基本功,常年开班收徒(一年学徒制度),每年10个名额。
商业合作加微信,项目接包与外包。