C位域操作
位域的概念
1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字节划分成不同的区域,每个区域都有个位域名,程序员可以代码通过位域名访问其中的数据。
位域的声明
类型 位域名:位域长度;
位域结构体,我理解是一种特殊的结构体,其成员变量都是位域,声明如下
struct 位域结构名
{
类型说明符 位域名:位域长度;
...
类型说明符 位域名:位域长度;
};
基本原则
现有一个简单的结构体
typedef struct Test1
{
char a:;
int b:;
}test1;
1. 位域变量的长度不能大于其类型的长度(sizeof(类型) * 8)
变量char has_assoc的类型位char 1字节 8位,小于定义的10,所以编译器警告
2. 不能用于位域字段的操作:取地址操作符&,取偏移量操作
位域是若干位空间,是没有地址的
3. 位域可以是无名位域,无名位域只能用作填充或调整位置,不能使用。
typedef struct Test1
{
char a:;
int b:;
int :;
}test1;
4. 位域字段不能声明为类的静态成员
5. 位域结构体的大小必须是其最长基本类型大小的整数倍(sizeof(类型) * 8)
6.如果一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
struct bs
{
unsigned a:
unsigned : /*空域*/
unsigned b: /*从下一单元开始存放*/
unsigned c:
}
这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
7.不够一个类型的size时,将按其中最大的那个类型对齐。
struct foo4 {
char a : ;
char b : ;
int c : ;
};
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:;
int b:;
}test1;
//运行结果:4
typedef struct Test1
{
char a:;
int b:;
long c;
}test1;
//运行结果:16
总结:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,GCC采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
C位域操作的更多相关文章
- 用union 和 struct 位域操作
很久没有用C 语言中的 union 和 struct 位域操作了. 最近用了一下(当然,我承认是从stackoverflow 上抄的) 需求是这样的,已知一个 LPARAM 整数 3866625 ,求 ...
- 【C/C++开发】关于位域操作
几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存对齐全攻略–涉及位域的内存 ...
- C\C++ 位域操作
几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存对齐全攻略–涉及位域的内存 ...
- 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)
一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...
- C语言中结构体的位域(bit-fields)
转自:http://blog.sina.com.cn/s/blog_6240b5980100tcba.html 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一 ...
- C结构体之位域(位段)
C结构体之位域(位段) 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C ...
- C语言基础--结构体对齐,位域,联合体
结构体对齐 1--结构体对齐的原因与意义 许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值K(通常是2,4,8)的倍数,而这个k则被称为该数据类型的对齐模数 ...
- [转]C结构体之位域(位段)
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构 ...
- 【转】C语言中结构体的位域(bit-fields)
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构 ...
随机推荐
- js异步执行 按需加载 三种方式
js异步执行 按需加载 三种方式 第一种:函数引用 将所需加载方法放在匿名函数中传入 //第一种 函数引用 function loadScript(url,callback){ //创建一个js va ...
- 15. 3Sum、16. 3Sum Closest和18. 4Sum
15 3sum Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = ...
- ST表求区间最值
#include<bits/stdc++.h> #define ll long long #define lowbit(x) x&-x using namespace std; ; ...
- 你所不知道的Hello World[C++实现]
要说OIer界内最简单的程序,那恐怕非Hello World莫属了, 那么这篇文章就介绍如何写Hello World(被打). 最简单的一种实现: #include <iostream> ...
- 添加一个layer
let testLayer = new TestLayer1();this.addChild(testLayer); let TestLayer1 = cc.Layer.extend({ ctor:f ...
- Win10激活工具 —— HWIDGen的使用方法
一:引言 众所周知,Windows系统在安装完成之后,第一步就是激活系统,网上的一些激活方法大多数都是KMS激活,激活持续时间为半年. 因此,我找到了一个可以永久激活的工具:HWIDGen,它可以数字 ...
- range()用法
来源:http://www.cnblogs.com/wangwp/p/4535299.html 例子:http://www.cnblogs.com/hongten/p/hongten_python_r ...
- 关于微信小程序
1.设置了tabBar的页面,好像用navigator跳不过去.
- Redis 数据结构的底层实现 (一) RealObject,embstr,sds,ziplist,quicklist
一.realObject Redis使用 string list zset hash set 五大数据类型来存储键和值.在每次生成一个键值对时,都会生成两个对象,一个储存键一个储存值.redis定义了 ...
- Markdown进阶教程
Markdown是很好用的轻量级标记语言,许多开发人员喜欢使用Markdown来记录学习心得和写博客.本篇博客主要介绍Markdown的高级技巧教程,Markdown的基础教程已经在上篇介绍过了. ...