C语言位域简介

#include <stdio.h>
/* 定义简单的结构 */
struct
{
    unsigned int widthValidated;
    unsigned int heightValidated;
} status1;

/* 定义位域结构 */
struct
{
    unsigned int widthValidated : 12;
    unsigned int heightValidated : 21;

} status2;

int main()
{
    printf("Memory size occupied by status1 : %d\n", sizeof(status1));
    printf("Memory size occupied by status2 : %d\n", sizeof(status2));

    return 0;
}

得出的结果是:

Memory size occupied by status1 : 12
Memory size occupied by status2 : 8

位段,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。来自百度百科

下面是一些规则:
规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,: 后面的数字不能超过这个长度。

如果将heightValidated的位数改为了33,就会超出int的最大位数4X8=32,
程序会报错:
	位域的大小无效
/* 定义位域结构 */
struct
{
    unsigned int widthValidated : 12;
    unsigned int heightValidated : 33;

} status2;

规定,只有有限的几种数据类型可以用于位域。在 ANSI C 中,这几种数据类型是 int、signed int 和 unsigned int(int 默认就是 signed int);到了 C99,_Bool 也被支持了。

规定, 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止。若其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

status1的大小是4,因为12+20=32,没有超出int的最大长度
status2的大小是8,因为12+21=33,超出int的最大长度
/* 定义位域结构 */
struct
{
    unsigned int widthValidated : 12;
    unsigned int heightValidated : 20;

} status1;
/* 定义位域结构 */
struct
{
    unsigned int widthValidated : 12;
    unsigned int heightValidated : 21;

} status2;

规定,如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6,VS2019采取不压缩方式,Dev-C++,GCC采取压缩方式;

在VS中执行得到:Memory size occupied by status2 : 8
在Linux下GCC中执行得到:Memory size occupied by status2 : 4
struct
{
    unsigned int widthValidated : 12;
    bool heightValidated : 1;

} status2;

规定,整个结构体的总大小为最宽基本类型成员大小的整数倍。

规定,如果位域字段之间穿插着非位域字段,则不进行压缩;

struct
{
    unsigned int widthValidated : 12;
    double heightValidated ;
    unsigned int widthValidated1 : 14;
} status2;
发布了20 篇原创文章 · 获赞 0 · 访问量 265

猜你喜欢

转载自blog.csdn.net/although1/article/details/104371159
今日推荐