位段

位段在使用中的注意点

  • 位段的成员必须是int、unsigned int 、signed int、char、long(属于整型家族)

  • 位段占的二进制位数不能超过该基本类型所能表示的最大位数

  • 无名位段不能被访问,但是会占据空间

  • 该结构占用的最少空间为其中最大类型所占的全部空间

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

  • 若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元(这里的位段存储单元经测试在VC环境下是4个字节,在linux下是1个字节)开始存放;

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

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

  • 位段不能出现数组的形式

  • 位段的空间上是按照4个字节(int)或者1个字节(char)的方式来开辟的

位段结构在内存中的存储方式

  • 如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。

  • 如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;

测试代码

/*测试位段 201110.12*/ 
#include<iostream>
using namespace std; 
 
typedef struct node
{
    unsigned int a:1;      //存在一个非0位的位段,则至少占4Byte 
}S; 
 
typedef struct node1       //在C++中占1字节的空间 ,在C中占0字节 
{
    unsigned int :0;
}S1;
 
typedef struct node2
{
    unsigned int a:1;
    unsigned int  :0;     //下一个位段放在一个新的位段存储单元 ,所以占4+4=8Byte 
    unsigned c:32;         
}S2;
 
typedef struct node3
{
    unsigned int a:4;
    unsigned int  :0;
int :6;               //这个位段放在一个新的位段存储单元 
    unsigned c:32;        //由于6+32>32,所位段c也放在一个新的位段存储单元,所以占4+4+4=12Byte 
}S3;
 
typedef struct node4  
{
    unsigned int a:1;
char b;                //在一个位段存储单元中能够存下所有的成员,所以占4Byte 
    int c:1;
int d:2;
    unsigned int e:2;
}S4;
 
 
int main(int argc, char *argv[])
{
    S4 s4;
    s4.a=1;
    s4.c=1;
    s4.d=2;              
    s4.e=3;
    printf("%d %d %d %d\n",s4.a,s4.c,s4.d,s4.e);
    printf("%d %d %d %d %d\n",sizeof(S),sizeof(S1),sizeof(S2),sizeof(S3),sizeof(S4));
return 0;
}

对于位段的不跨平台解释如下

  1. int位段被当成有符号或是无符号是不确定的(linux下是signed),对于取出的数据会进行符号扩展
typedef struct Data1
{
	signed int a:5;
	signed int b:2;
}data1;
int main(int argc, char ** argv)
{
	data1 d;
	d.a = 1;
	d.b = 2;
	printf("%d %d\n",d.a, d.b);
	return 0;
}

结果为1, -2

  1. 位段中最大位的数目不能确定(16位机器最大16,32位机器最大32,如果数字写为27,在16位机器是不可以的);

  2. 位段中的成员在内存中是从左向右分配,还是从右向左分配尚未定义

总结

位段和结构相比,可以达到同样的效果,可以很好节省空间,但是存在不跨平台问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值