位段的内存分配
位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
例子
(因为位段不确定性我们演示VS2019的版本):
//一个例子struct S{ char a:3; char b:4; char c:5; char d:4;};int main(){ struct S s = {0}; s.a = 10; s.b = 12; s.c = 3; s.d = 4; return 0;}
位段的跨平台问题
int 位段被当成有符号数还是无符号数是不确定的。
位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机 器会出问题。
位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义
当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的
位段可以很好的节约空间但是跨平台能力极差.我们使用位段时我们要先观察自己平台位段的规则.
位段的应用
对每个信息进行到比特的控制大大增加了空间的利用率
枚举
枚举的作用和#define类似都是将字母变成常量但是枚举相较于#define更有优点
增加代码的可读性和可维护性
和#define定义的标识符比较枚举有类型检查,更加严谨。
防止了命名污染(封装)
便于调试
使用方便,一次可以定义多个常量
枚举的使用
enum Color//颜色{ RED=1, GREEN=2, BLUE=4};int main(){ enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。 clr = 5; return 0;}
此代码在C编译器可以正常使用
但是在cpp编译器时会报错
当我们不对枚举类型内元素初始化时会自动以递增的形势进行赋值从0开始
下面对枚举不同赋值情况进行展示:
所有都没赋值:
则RED=0 GREEN =1 BLUE =2
对RED赋值
如
RED= 1 时
RED=1 GREEN =2 …
只对GREEN赋值:
如GREEN = 2;
RED =0 GREEN =2 BLUE = 3
我们枚举内元素均为常量不可赋值改变.
联合(共用体)
联合类型的定义
联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
可以观察到他们的地址相同
union Un{ char c; int i;};//联合变量的定义int main(){ union Un un; //计算连个变量的大小 printf("%d\n", sizeof(un));//4 return 0;}
联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
联合体大小的计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
比如
union Un1{ char c[5]; int i;};//大小为8union Un2{ short c[7]; int i;};//大小为16
第一个因为char a[5]是char类型他的对齐数为1 int类型的对齐数为4
原本他们共用同一份空间大小为5
但联合体大小要对齐到最大对齐数的整数倍及4的整数倍8.
第二个同理
short类型的对齐数为2 int类型对齐数为4
原本公用一块内存大小为14(7*2)
但要对齐到最大对齐数的整数倍及4的整数倍还要大于14所以为16
结尾
本章知识多为定义后面会以通讯录为练习.