有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。

例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进
制位域来表示。
一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为: 
struct 位域结构名 
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度 
例如: 
struct bs
{
int a:8;
int b:2;
int c:6;
};
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:
struct bs
{
int a:8;
int b:2;
int c:6;
}data;
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
例如: 
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元开始存放*/
unsigned c:4
}
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如: 
struct k
{
int a:1
int :2 /*该2位不能使用*/
int b:3
int c:2
};
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。
如果结构体中含有位域(bit-field),那么VC中准则是:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式;
系统会先为结构体成员按照对齐方式分配空间和填塞(padding),然后对变量进行位域操作。
理解了吗?试着做下面几个例子(VS 2003)。
#pragma pack(1) 
struct s4{
char a:4;
short b:4;
short c:4;
long d;
};
输出S4 sizeof:7
#pragma pack(1) 
struct s4{
char a:4;
short b:4;
char c:4;
long d;
};
输出S4 sizeof:8
#pragma pack(2) 
struct s4{
char a:4;
short b:4;
char c:4;
long d;
};
输出S4 sizeof:10
#pragma pack(2) 
struct s4{
char a:4;
short b:4;
short c:4;
long d;
};
输出S4 sizeof:8
#pragma pack(2) 
struct s4{
char a:4;
short b:4;
short c:7;
long d;
};
输出S4 sizeof:8
本文转自 驿落黄昏 51CTO博客,原文链接:http://blog.51cto.com/yiluohuanghun/1181675,如需转载请自行联系原作者

C中位域结合对齐(pragma)的例子及解释相关推荐

  1. mysql字节对齐_结构体字节对齐-位域及其对齐

    字节对齐的准则:其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 2) 结构体每个成员相对于结构体首地址的偏移量都是成 ...

  2. 关于C++中四字节对齐的坑

    最近做一个工程,大体的意思是在程序中定义一个结构,运行中会将结构直接写到文件中,然后另一个程序会用同样的结构读出来.为了验证是写文件的程序的问题还是读文件的程序的问题,用winhex来打开文件,仿照结 ...

  3. 计算机中的字节对齐问题

    [转载]http://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 ...

  4. 面试常考,项目易错,长文详解C/C++中的字节对齐

    作者 | 李肖遥 来源 | 技术让梦想更伟大(ID:TechDreamer) 头图 |  CSDN 下载自东方IC 引入主题,看代码 我们先来看看以下程序 //编译器:https://tool.lu/ ...

  5. 位地址和字节地址换算_面试常考,项目易错,长文详解C/C++中的字节对齐

    (给CPP开发者加星标,提升C/C++技能) 作者:技术让梦想更伟大 / 李肖遥 (本文来自作者投稿) 我们先来看看以下程序 //编译器:https://tool.lu/coderunner///来源 ...

  6. C语言中的字节对齐以及其相关处理

    首先,我们来了解下一些基本原理: 一.什么是字节对齐 一个基本类型的变量在内存中占用n个字节,则该变量的起始地址必须能够被n整除,即: 存放起始地址 % n = 0,那么,就成该变量是字节对齐的;对于 ...

  7. 64位 int 占几个字节_面试常考,项目易错,长文详解C/C++中的字节对齐

    面试常考,项目易错,长文详解C/C++中的字节对齐​mp.weixin.qq.com 引入主题,看代码 我们先来看看以下程序 //编译器:https://tool.lu/coderunner/ //来 ...

  8. 面试常考,项目易错!C/C++中的字节对齐

    作者 | 李肖遥 来源 | 技术让梦想更伟大(ID:TechDreamer) 头图 |  CSDN 下载自东方IC 引入主题,看代码 我们先来看看以下程序 //编译器:https://tool.lu/ ...

  9. @entity 不限字节长度的类型_面试常考,项目易错,长文详解C/C++中的字节对齐...

    面试常考,项目易错,长文详解C/C++中的字节对齐​mp.weixin.qq.com 引入主题,看代码 我们先来看看以下程序 //编译器:https://tool.lu/coderunner/ //来 ...

最新文章

  1. 世界最优秀的分布式文件系统架构演进之路
  2. 元气森林网络推广外包来势汹汹,地毯式营销旨在打造国民品牌
  3. python中怎么输出中文-python中使用print输出中文的方法
  4. 停止宗教战争,好吗?
  5. HDU-4059 The Boss on Mars 容斥定理
  6. linux redis客户端_为什么单线程Redis能那么快?
  7. linux 关闭ext3日志,ssh – 可以在Linux(ext3)上减慢日志写入速度吗?
  8. 基坑监测日报模板_深基坑又出事,广西工地 10m深 基坑坍塌,4名钢筋工被埋,3人遇难!...
  9. Python Tricks(十四)—— list 逆序的实现
  10. Linux 系统服务之间 实现免密登陆
  11. 括号里面一个上面一个数下面一个数符号怎么打?/ 概率论组合符号怎么打?
  12. BAT面试高级进阶,Java架构师之路
  13. 从零开始的Origin新手入门教程(速成)
  14. 老板突然出现,游戏飞速隐藏,开源神器在手,摸鱼不怕被抓包丨不会写代码也能用...
  15. radius源码下载
  16. STM32控制舵机及其原理
  17. HDOJ-2154-跳舞毯
  18. asp存入当前时间mysql_asp当前日期时间
  19. mysql语法 join on 表示什么
  20. java.io.FileNotFoundException: File does not exist: hdfs ://sxt/home/sqoop-1.4.6/lib/commons-codec-1

热门文章

  1. 软件导航html单页源码
  2. dedecms织梦仿麦站网模板源码下载站源码
  3. linux中如何运行html文件路径问题,Linux中如何查询运行文件的全路径的方法
  4. pdf.js使用方法整理,web页面中pdf在线查看,web页面显示pdf文档
  5. 电脑设置代理IP工具 可自动更新
  6. 简单易懂的破解脱壳从0开始
  7. Enterprise Library系列文章目录
  8. mysql —— 分表分区
  9. Python 3 教程一:入门
  10. 用代码证明自己闲的蛋疼(一)——cmd闪瞎狗眼