C位域操作

位域的概念

1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字节划分成不同的区域,每个区域都有个位域名,程序员可以代码通过位域名访问其中的数据。

位域的声明

类型 位域名:位域长度;

位域结构体,我理解是一种特殊的结构体,其成员变量都是位域,声明如下

struct 位域结构名
{
  类型说明符 位域名:位域长度;
  ...
  类型说明符 位域名:位域长度;
};

基本原则

现有一个简单的结构体

typedef struct Test1
{
    char a:1;
    int b:2;
}test1;

1. 位域变量的长度不能大于其类型的长度(sizeof(类型) * 8)

变量char has_assoc的类型位char 1字节 8位,小于定义的10,所以编译器警告

2.  不能用于位域字段的操作:取地址操作符&,取偏移量操作

位域是若干位空间,是没有地址的

3. 位域可以是无名位域,无名位域只能用作填充或调整位置,不能使用。

typedef struct Test1
{
    char a:1;
    int b:2;
    int :1;
}test1;

4. 位域字段不能声明为类的静态成员

5. 位域结构体的大小必须是其最长基本类型大小的整数倍(sizeof(类型) * 8)

6.如果一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:

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

这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。

7.不够一个类型的size时,将按其中最大的那个类型对齐。

struct foo4 {
    char    a : 2;
    char    b : 3;
    int c : 1;
};

foo4中虽然三个位域所占用空间之和为6 bit < 8 bit(1 byte),但是由于char和int的对齐系数是不同的,是不能捆绑在一起,那是不是a、b捆绑在一起按照char对齐,c单独按照int对齐呢?我们 打印一下sizeof(struct foo4)发现结果为8,也就是说编译器把a、b、c一起捆绑起来并以int做对齐了。

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

typedef struct Test1
{
    char a:1;
    int b:2;
}test1;
//运行结果:4
typedef struct Test1
{
    char a:1;
    int b:2;
    long c;
}test1;
//运行结果:16

总结:

1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,GCC采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

原文地址:https://www.cnblogs.com/WindSun/p/11283910.html

时间: 2024-10-19 08:21:45

C位域操作的相关文章

用union 和 struct 位域操作

很久没有用C 语言中的 union 和 struct 位域操作了. 最近用了一下(当然,我承认是从stackoverflow 上抄的) 需求是这样的,已知一个 LPARAM 整数 3866625 ,求他的第30位的值是多少. 解法也挺简单 int a = 3866625; a = a>>30 & 0x0001; //注意是右移动30,而不是29,因为第一位是0 ,我一开始就移动的29 结果算错! 但是我偶然在stack over flow 上看到了 另外一种方案 union KeySt

【转】c语言位域操作—_结构体内冒号:的使用

原文链接:http://blog.chinaunix.net/uid-22145625-id-1789513.html 这是C语言位域问题 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”.所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作.这样就可以

位域操作

看runtime源码时,看到如下声明变量的,变量后分号前加冒号和数字": 数字"即为位域操作. uintptr_t indexed : 1; 1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字节划分成不同的区域,每个区域都有个位域名(可以理解为变量名,上边的代码中位域名为indexed),程序员可以代码通过位域名访问其中的数据. 一. 声明 类型说明

C语言中位域操作

C语言中位域定义: 以结构体中定义申明变量的形式: 类型说明符 位域名:位域宽度 struct bit{ int a:4; // 申明位域变量a,占用4个bit位宽度 int b:4; // 申明位域变量b,占用4个bit位宽度 int c:4; // 申明位域变量c,占用4个bit位宽度 }; 在gcc编译器中对结构体进行了默认的对齐操作,以下的所有的现象都是基于gcc的编译条 件:1):申明的两个相连的位域变量占位一般都是紧密连接的,例如上面的a和b,或者是b和 c:a占用起始字节的低4位,

C\C++ 位域操作

几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存对齐全攻略–涉及位域的内存对齐原则 本文主要对位域相关知识进行了一下梳理,参考如下: C语言中的位域 史上最全的C位域总结2 C结构体之位域(位段) C/C++中以一定区域内的位(bit)为单位来表示的数据成为位域,位域必须指明具体的数目. 位域的作用主要是节省内存资源,使数据结构更紧凑. 1. 一个位域必须存储在同一个字节

C结构体之位域(位段)

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”.所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作. 这样就可以把几个不同的对象用一个字节的二进制位域来表示.一.位域的定义和位域变量的说明 位域定义与结构定义相仿,其形式为: struct 位域结构

C语言位域

原贴地址http://www.cnblogs.com/bigrabbit/archive/2012/09/20/2695543.html 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”.所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作. 这样就可

C语言中结构体的位域(bit-fields)

转自:http://blog.sina.com.cn/s/blog_6240b5980100tcba.html 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”.所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作.这样就可以把几个不同的对象用一个字节的

嵌入式系统编程和调试技巧

嵌入式系统的开发,软件的运行稳定可靠是非常重要的.在芯片中,软件是没有质量的,但软件的质量可以决定一颗芯片的成败.芯片设计中,性能能否满足设计要求,除了硬件设计.软硬件配合的设计技巧,对于软件来说,编程的一些技术和技巧同样重要. 本文讲述我在芯片固件开发过程中使用的一些编程调试技巧.针对在嵌入式系统开发中常见的问题,如实时系统下的同步问题,动态内存分配的内存泄漏问题,如何在编程阶段预防BUG出现,调试阶段如何及时发现问题和定位问题.总结下经验,目的是开发一个稳定运行的固件,提高开发效率,提高运行