位段的定义、内存分配、应用

//二、————位段(位段是通过结构体来实现的)只可用于结构体
2.1 什么是位段
位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是(整型家族) int、unsigned int 或signed int 。
2.位段的成员名后边有一个冒号和一个数字(数字大小不可以超过对应类型的比特位)。
3.位段是可以用来节省空间的
//#include<stdio.h>
//struct A//A就是一个位段类型。
//{
//    //int为4字节=32比特位,但是_a只需两个比特位
//    int _a : 2;//_a是成员名字
//    int _b : 5;//:2表示其前面的成员只占两个比特位(或者说是给_a分配两个比特位)
//    int _c : 10;//当成员的取值范围是非常有限的情况下,那我们所需要的内存空间也就可以一定程度上减小
//    int _d : 30;
//};
//int main()
//{
//    printf("%d\n", sizeof(struct A));
//    return 0;
//}
那位段A的大小是多少?
由于成员类型为int,所以每次开辟4字节,而a,b,c,d共占用47个字节。
47>32字节,所以需要开辟新的空间来存放,因此大小为8字节

2.2 位段的内存分配
1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以每次4个字节( int )或者每次1个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植性的程序应该避免使用位段。
//#include<stdio.h>
//struct S
//{
//    char a : 3;
//    char b : 4;
//    char c : 5;
//    char d : 4;
//};
//int main()
//{
//    struct S s = { 0 };
//    printf("%d\n",sizeof(struct S));
//    s.a = 10;//转成二进制为:1010,由于a只需要4个比特位,所以由低到高截断为010
//    s.b = 12;//转成二进制为:1100
//    s.c = 3;//转成二进制为:101,由于a只需要5个比特位,所以补0为00101
//    s.d = 4;//转成二进制为:100,由于a只需要4个比特位,所以补0为0100
//    return 0;
//}
空间是如何开辟的?两个char即两个字节=16比特位
内存排布(由低到高—>从左向右)为(以小端排序排布):
高地址                                          低地址
 01100010 00000011 0000000 00000000  值为:14200600000(10进制)
 0x62030000十六进制为24c(每四个2进制位为一个16进制位)

2.3 位段的跨平台问题
1. int 位段被当成有符号数还是无符号数是不确定的。
2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题)
3. 位段中的成员在内存中从是左向右分配,还是从右向左分配尚未定义(也要考虑大小端问题)
  即,在内存中的排布顺序未定义,在不同环境下是不同的。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的比特位时,是
  舍弃剩余的位还是利用,这是不同编译器下是不确定的。
总结:跟结构体相比,位段可以达到同样的效果(如果设计成位段式的这种结构,
//        能够达到结构体想要的效果的话,位段是可以节省更多空间的)但是有不可跨平台的问题存在。
注意:位段这个语法的设计本身是不可跨平台的,但是我们能写出带有跨平台性的代码(针对不同的平台写出不同的代码)

4.———— 位段的应用(多用在网络中)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值