位段
位段的介绍
位段与结构体很类似,只有些许不同。
struct A
{
int a:1;
int b:5;
int c:10;
};
从形式上看,位段和结构体大体相同
a,b,c是位段的成员
位段的成员类型只能是signed int ,unsigned int, int,char,整型类型(char是特殊的整型类型)
每个成员名后面有一个":"和数字。
数字代表这个成员占几个二进制位(bit).
1字节=8bit.
int类型在结构体里开辟的空间有32bit,但是有些数字根本用不了那么大的空间,而位段里面就可以手动限制所开辟空间的大小。在已知成员占用不大时,就能用位段进行限制。
位段的内存分配
位段不像结构体,不用对齐。
位段按照需要,以int(4字节),char(1字节)进行开辟空间,然后依次放入成员(成员大小是自己限制的),不够了再按需求,开辟int(4字节),char(1字节)大小的空间。
在VS环境下
struct A
{
char a:3;
char b:4;
char c:5;
char d:4;
};
int main()
{
struct A X={10,12,3,4};
return 0;
}
位段的跨平台问题
1.int位段被当成有符号数还是无符号数是不确定的。
2.位段中最大位的数目不能确定(在32位机器上,限制位可以写27位,但是在16位机器上就会错
3.位段中的成员在内存中从左往右分配,还是从右往左分配的标准尚未定义,所以上述的例子只能在vs环境下才能100%生效。、
4.当开辟的一个空间位置不够,要开辟下一个空间时,上一个空间剩下的位置是舍弃还是利用是不确定的,像这里vs环境下是舍弃。
综上所述,位段能和结构体达到相同的效果,而且能更加节省空间,但是不好跨平台。
枚举
枚举就是把可能的值一一列举,它的作用是定义常量
枚举类型的定义
enum Sex
{
male,
female,
secret
};
male,female.secret是枚举常量,是常量,拥有常量的所有性质
!注意!最后一个枚举常量后面是没有","的。
可以写成
enum Sex
{
male=1,//注意这里
female,
secret
};
int main()
{
enum Sex a = male;
}
能在定义枚举类型时,就给与这些枚举常量一个值(虽然常量的规则时不能被赋值,但是这里时给常量最开始的值)。
emun Sex a = male;等价于int a = 1;
一样的效果,都是初始化a。
如果定义了male = 1,后面的female和secret就会自动依次递增,female = 2 ,secret = 3.
如果既没有被定义,上面也没有别的以及定义的枚举变量,那这个枚举变量就是默认值=0.
枚举的优点
之前了解到,#define 也能用来定义常量 ,枚举相比之下有些优点
1.可以增加代码的可维护性和可读性。
比如分支功能switch case,一般使用case1....case2...这样写,现在可以用枚举定义case1对应的操作的名字为常量1,假设操作时开始游戏,就可以定义常量start为1,然后就可以改成 case 1----->case start,这样分支作用就一目了然了。
2.相比于#define,枚举常量是有类型的,有类型检
查,#define的本质是替换,枚举更加严谨
3.便于调试,枚举是能调试的,能看到定义常量的过程。
4.防止命名污染
5.使用更加方便,能一次性定义多个常量。
联合(共用体)
联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列成员,特征是这些成员公用同一块空间(所以联合体也叫共用体
联合的类型定义
union UN
{
char c;
int i;
};
int main()
{
union UN X;
return 0;
}
联合体特点
两个成员共用空间,蓝色部分即时c的空间,又是c与i重叠的空间。
所以量成员不能同时使用,因为在使用一个的时候,必定会影响另外一个
联合体大小计算
1.联合体大小至少是最大成员大小。
从上面的图可以看出,要想联合体能容纳的下所有成员,至少要大于最大的成员大小。
2. 当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍
union UN
{
char c[5];//可以看成是5个char类型的成员,每个对齐数是1,但是整体大小是5
int i;
};
最大成员大小是5,5不是最大对齐数4的整数,所以对齐到8,大小是8.
用联合体的特性,来判断电脑是大端还是小端。
union UN
{
char c;
int i;
}un;
int main()
{
un.i=1;
if(un,c==1)
printf("是小端");
else
printf("是大段");
return 0;
}
在执行un.i=1;这个代码后,内存中存储如下。
(此时是小端)小端存储,高位在低地址处,01就会跑到c能访问的空间里。