1.位段
1.1位段的定义
位段的声明和结构体是类似的,但是有两个不同
1.位段的成员必须是整型类型的,且每个位段内的成员要保证类型一致。
2.位段的成员后边有一个冒号和一个数字。
比如:
struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};
如此定义的话,A就是一个位段类型,那么,这样开辟一个位段类型,他在内存中占据的空间是多大呢?
结果如下所示:
此位段在内存中占用的空间是8个字节。
为什么会存在这样一个现象呢,那下面我们就来聊一聊位段在内存中的存储方式。
1.2位段在内存中的存储方式
1.位段成员必须是属于整型家族类型的,并且每个位段中的成员类型都是相同的。
2.位段的空间上是需要4个字节(int等类型)或者1个字节(char)的方式来开辟的。
3.位段涉及很多不确定因素,因此位段是不跨平台的,注重可移植的程序应该避免使用位段。
那么,首先我们来分析一下上面提到的A这个位段的储存方式。
位段,顾名思义,是通过为来开辟空间的。
首先,定义位段以后,需要来开辟空间,由于A是int类型的,所以通过4个字节来开辟空间,也就是先开辟32位。
-
首先,先开辟a的内存空间,a占2位的空间。
-
然后开辟b的内存空间,b占5位的内存空间。
-
然后开辟c的内存空间,c占10位的内存空间。
-
这样,a,b,c加起来就占据了17位的内存空间了,剩余15位内存空间,但是d需要占用30位内存空间。
-
所以就会将剩下15位内存空间浪费掉,再开辟4个字节来存储d,这样加起来就是8个字节的空间。
位段最大不能超过32位,如果超过32位就会报错。
所以位段在使用int类型的数据的时候,在内存中就是这样存储的,而使用char类型的时候,是一个字节一个字节即8位8位来开辟的,和int类型的略有不同,不过也很好理解。
1.3位段的跨平台问题
- int位段被当成有符号数还是无符号数是不确定的。
- 位段中最大位的书目不能确定(16位机器最大16,32位机器最大32,写成27,在16位机器中会出问题。)
- 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
- 当一个结构包含两个位段,第二个位段成员比较大,无法容纳第一个位段剩余的位时,是舍弃剩余位还是利用,这是不确定的。
总结:
- 跟结构体相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。
1.4位段的应用
位段当然也有比较重要的用处,当我们要传输数据的时候,需要用到很多的校验码等内容,这样如果直接用字节来当校验码的时候,就会占用很大的空间,这样对于数据的传输并不是很友好,这时,位段的重要性就体现出来了。
用位段就可以很好地节省空间,更利于传输数据。
2枚举
枚举顾名思义就是将可能的取值进行一一列举,比如说,我们现实生活中,一周有星期一到星期天是有限的七天,可以进行一一列举;月份有12个月,也可以进行一一列举。这样就可以是使用枚举类型了。
2.1枚举类型的定义
enmu Day
{
Mon,
Tust,
Wed,
Thur,
Fri,
Sat,
Sun
};
枚举就是按照上面的方法来进行定义的
其中的Mon,Tust等都是枚举常量,在定义过程中就已经赋好了初值,所以在调用过程中是不能修改这些枚举常量的值的。
默认情况下,Mon的值为0,Tust的值为1,以此类推,但是我们也可以在赋初值的过程中,给这些枚举常量定义初始的值。具体的定义方法如下:
enum Day
{
Mon=3,
Tust=5,
Wed=7,
Thur,
Fri,
Sat,
Sun
};
这样就可以将Mon的值定义为3,Tust的值定义为5。
2.2枚举的优点
我们可以使用#define来定义常量,为什么非要使用枚举呢?
枚举的优点:
- 增加代码的可读性和可维护性。
- 和#define定义的标识符比较枚举有类型检查,更加严谨。
- 防止了命名污染(封装)。
- 便于调试。
- 使用方便。
以上内容就是我对于位段和枚举的一些理解,当然还有很多没有理解到的地方,希望各位兄弟姐妹可以给我批评指正,小弟不胜感激!!!