前面我们说过了自定义类型,包含结构体,位段,枚举,联合。前一篇我们总结了结构体,今天来说一下位段,枚举,联合。
一、位段
1、位段概念
C语言中允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单元的成员称为“位段”或“位域”。
(1)位段的成员可以是int,unsigned int,signed int,都是整形类型。
(2)位段后面有一个冒号和一个数字,这个数字代表位段所占的二进制位数。(这个数字不能超过32,因为int 开辟的是四个字节的空间,最多只有32个 bit 位)
2、位段的存储
首先先看变量的类型,开辟类型大小的字节数,然后看位段后面的数字,是几就占用几个bit位,剩余的bit位留给下一个变量使用。如果空间不够就开辟对应类型大小的字节数。
对于位段结构,编译器会自动进行存储空间的优化,保持以下两个原则。
(1)一个位段存储单元如果可以存储下位段的所有成员,那么这些成员必须要放入一个位段存储单元,不能放入两个位段存储单元。如果不可以存储下所有成员,那么剩余的位段成员从下一个存储单元开始存储。
(2)如果位段结构中,只有一个占有0位的无名位段,则只占0或1的字节的空间。(C语言占0字节,C++占1字节),否则剩下的情况至少占用一个位段存储单元。(无名位段不可以被访问,但是会占据空间)
(3)举个例子
struct X
{
int _a:2;
int _b:3;
int _c:5;
int _d:6;
}a;
此例中,我们计算位段X,首先我们看类型是int,开辟的是4个字节大小的存储单元,a是 2 bit,b是 3 bit,c 是 5 bit,d是 6 bit,加起来一共是16 bit, 但是开辟的是4字节的存储空间,所以用sizeof求位段X的大小是4字节。
二、枚举
1.枚举的概念
枚举顾名思义,就是一一列举,把可能的取值一一列举出来。例如星期,性别,月份,颜色。
enum Day
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum 就是枚举类型,{ }中的内容就是枚举类型的可能取值,称为 枚举常量。这些可能取值都是有值的,默认从0开始,一次递增1,在定义的时候也可以赋初值。在赋值的时候需要注意,可以把枚举常量赋给枚举变量,但是不可以把枚举常量的数值赋给枚举变量。比如 Day 1=Mon是正确的,但是Day 1=1就是错误的。
2、枚举的优点
(1)增加代码的可读性和可维护性
(2)和#define定义的标识符比较,枚举有类型检查,更加严谨。
(3)防止了命名污染
(4)便于调试
(5)使用方便,一次可以定义多个常量
三、联合
1、联合的概念
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间,所以联合也称为共用体。
2、联合的计算
(1)联合的成员是共用同一块内存空间的,这样一个联合的大小至少是它最大成员的大小。
(2)当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
printf("%d\n",sizeof(union Un1));//8
printf("%d\n",sizeof(union Un2));//16