//////二、————位段(位段是通过结构体来实现的)只可用于结构体

////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.———— 位段的应用(多用在网络中)