1 介绍
有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。这在寄存器操作上用的较多些,如PLC行业modbus通信,位寄存器可能需要5个不需要一个字节。
2 结构体定义示例
typedef struct {
char name:6;
char city:2;
} DATA;
- :后面的数字用来限定成员变量占用的位数。
- C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:后面的数字不能超过这个长度。
3 支持类型
- C语言标准还规定,只有有限的几种数据类型可以用于位域。
- 在 ANSI C 中,这几种数据类型是 int、signed int 和 unsigned int(int 默认就是 signed int);
到了 C99,_Bool 也被支持了。 - 编译器在具体实现时都进行了扩展,额外支持了 char、signed char、unsigned char 以及 enum 类型,所以上面的代码虽然不符合C语言标准,但它依然能够被编译器支持。
4 位域存储
#include <stdio.h>
typedef struct {
char name:6;
char city:2;
} DATA;
int main()
{
DATA data;
printf("size of data: %ld\n", sizeof (data));
}
上述代码运行结果是1,结构体中位域成员紧邻存储占一个字节。
#include <stdio.h>
typedef struct {
int name:6;
int city:12;
int year:5;
} DATA;
int main(){
DATA data;
printf("size of data: %ld\n", sizeof (data));
}
上述代码运行结果是4,结构体中位域成员紧邻存储,共占23bit,之所以为 4,而不是 3,是因为要将内存对齐到 4 个字节,以便提高存取效率。
参考
1、C语言位域(位段)详解 2、请问 C语言里的 结构体中定义变量 后面的:是什么意思
|