C语言位域浅析

   位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。

位段的定义格式为:

type  [var]: digits

其中:

type只能为int,unsigned int,signed int,char, unsigned char 五种类型之一,digits表示该位段所占的二进制位数

  位段长度digits不能超过类型type对应的数据类型占用的大小,如若type为char,则digits不能超过8,为int则digits不能超过32

位段名称var是可选参数,可以省略

一、位域的定义

  位域定义与结构体定义相仿,其形式为: 
  struct 位域结构名 
  {

    位域列表

   }; 
  其中位域列表的形式为: type  [var]: digits

  例如:

 1 struct data{
 2
 3     int a : 32;          //位段a,占32位
 4
 5     char b : 5;             //位段b,占5位
 6
 7     char c : 2;            //位段c,占2位,和b存储在同一个字节
 8
 9     unsigned char : 6;          //无名位段,占6位
10
11 };

注:位域可以无位域名,这时它只用来作填充或调整位置,无名的位域不能被访问

  二、位段的使用

    位域的使用和结构成员的使用相同,其一般形式为:位域变量名·位段名,也可定义一个指向位域的指针p,然后p->位段名使用,使用时需要注意:

    ①不能对位段进行取地址操作

    ②若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元开始存放

    ③若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int

    ④对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果

  三、位段在内存中的存储模式

    使用位域的主要目的是压缩存储,其大致规则为:

  1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

  2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

  3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,经实验VC采取不压缩方式,即即使前一个字段有空余位足够容纳后一个字段,后一个字段也当前一个字段           没有空余位,从前一个字段类型大小之后的新字节开始存储;

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

  5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。:

  测试程序如下,环境vs3013,cfree 5.0

#include <stdio.h>

#include <stdlib.h>

struct data{     

    int a : 20;          //位段a,占20位

    char b : 3;             //位段b,占3位,不会和a压缩存储

    char : 0;           //无名位段

    unsigned char c : 5;  //位段c,占5位
};
int main()

{
    data test;
    data *ptest;
    ptest = &test;
    //两种方式访问位段
    test.a = 20;
    ptest->b = 5;

    //vc不压缩存储,占用8个字节,为其最宽基本类型成员大小的整数倍
    printf("sizeof(data): %d\n",sizeof(data));

    //test.b在输出时自动转化为整型,5(101)高位为1,扩展时高位连续补1,值为-3
    printf("test.a = %d\t test.b = %d\n",test.a, ptest->b);

    system("pause");
    return 0;

}

运行结果为:

sizeof(data): 8
test.a = 20 test.b = -3

  参考:

http://www.cnblogs.com/dolphin0520/archive/2011/10/14/2212590.html

  http://blog.sina.com.cn/s/blog_3d8529400100istl.html

时间: 2024-07-29 12:20:09

C语言位域浅析的相关文章

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

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

C语言位域

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

C语言位域的一些知识

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

c语言位域的使用注意事项——数据溢出

c语言可以使用位域来节省变量的空间,例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位.位域的取值范围非常有限,数据稍微大些就会发生溢出,这个字使用keil的使用,keil提示,溢出的警告, 因此不能忽视keil的任何警告,否则数据溢出了,你代码的功能是完不成的. struct pack{unsigned a:12;  unsigned  :20;//该位域成员不能使用,用于填充unsigned c:6;  }; 另一种是可以拿来填充,因为存在内存对齐的原因. 原文地址

C语言位域的定义和使用

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

C语言位域和大小端

工作中经常需要解析收到的数据报文,而报文中很多协议字段都用bit来表示.一般都会使用指针偏移然后右移的方式来获取响应的bit位的值.比如下面这样一个报文: D的值为:((pucPktAddr + 3)>>6) & 0x3  --偏移3个字节,右移6位,再与上掩码 E的值就是((pucPktAddr + 3)>>3) & 0x7 感觉不是很直观,可以试着用位域的方法来获取 1 typedef struct XXX { 2 unsigned char D:2 3 uns

[转] C中的位域

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

结构体、共用体和位运算

1.C语言结构体的定义和使用 在实际问题中,一组数据往往具有不同的数据类型:例如在学生信息登记表中,姓名为字符型,学号为整型或字符型,年龄为整型,性别为字符型,成绩为整型或实型.因为数据类型不同,显然不能用一个数组来存放. 在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据.定义结构体的一般形式为: struct 结构体名{ 成员列表 }; 每个成员都是结构体的组成部分,有名字,也有数据类型,形式为: 类型说明符 成员名; 例如用结构体来表示学生信息: struct stu{ c

C语言中文件打开模式(r/w/a/r+/w+/a+/rb/wb/ab/rb+/wb+/ab+)浅析

C语言文件打开模式浅析 在C语言的文件操作语法中,打开文件文件有以下12种模式,如下图: 打开模式  只可以读   只可以写  读写兼备 文本模式 r w a r+ w+ a+ 二进制模式 rb wb ab  rb+ (r+b)   wb+ (w+b)   ab+ (a+b)  其中,二进制模式与文本模式操作相似,只不过是以二进制流的形式读写而已,下面以文本模式为例分析: 1."r" 模式: 1.1 打开文件进行“只读”操作,即只能从文件读取内容. 1.2 若欲操作的文件不存在,则打开