位段就是C语言允许一个结构体以比特位来指定其成员所占内存长度,这种以比特位为单位的成员是位段。
类型可以是 int unsigned int signed int 或者是 char (属于整形家族)类型。
struct S
{
char a:5;
char b:4;
char c:4;
char d:3;
};
struct S s = {0};
s.a = 8;
s.b = 5;
s.c = 7;
s.d = 6;
如下代码,看看a,b,c,d的:
struct S
{
char a:5;
char b:4;
char c:4;
char d:3;
};
struct S s = {0};
s.a = 8;
s.b = 5;
s.c = 7;
s.d = 6;
1、按定义的位段,先分配好所需比特位占的空间,a只能占用5个,b占用4个,c占用2个,d占用3个。
2、如果下一个所需比特位位数满足不了此空间,那就再开辟一个char类型空间
3、按刚才所分配好的空间,对赋的值进行截断或者不够补0:a=8,二进制位是1000,不够5个,就补0即01000;b=5,二进制位是101,不够4个,补0即0101;c=7,二进制位是111,所需比特位是2,需要截断,即11,;d=6,二进制位是110,整好是3个。
4、把这些比特放到刚才的空间里得到:0000 1000 0011 0101 0000 0110 按每组4位换成16进制是0x 08 35 06。
验证结果如下图:
优点:
缺点:
联合体所有成员都共用一块内存,使用的时候,这些数据在同一个内存位置,关键字是union。
创建声明:
union Un//联合类型的声明
{
short a;
int i;
};
union Un un;//联合变量的定义
性质:
union Un
{
double i;
int a;
};
union Un un;
int main()
{
printf("%d\n", &(un.i));
printf("%d\n", &(un.a));
}
计算联合体大小需同时满足如下条件:
union Un1
{
char a[6];
int i;
};
union Un2
{
char b[9];
short i;
};
int main()
{
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));
return 0;
}
我们知道,数据在存储的时候超过一个字节,会涉及到顺序的问题。
分为两种:大端序和小端序。
有如下两种判断主机哪种存储方式
int check_sys()
{
union Un
{
char c;
int i;
}u;
u.i = 1;
return u.c;
}
int main()
{
int ret = check_sys();
if (ret == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
解析:
1、联合体创建一字节的char类型和4字节int 类型。
2、把int类型i变量赋为1(便于判断。
3、1是4字节int类型,小端16进制是0x 01 00 00 00 ,大端16进制是0x 00 00 00 01,所以在check_sys()函数里直接返回1字节char c即u.c,因为它是一字节,如果c拿到的是01说明是小端,如果c拿到的是00说明是小端。
验证结果:
int check_sys()
{
int num = 1;
return *(char*)#
}
int main()
{
int ret = check_sys();
if (ret == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
解析:
1、把int类型i变量赋为1(便于判断。
2、1是4字节int类型,小端16进制是0x 01 00 00 00 ,大端16进制是0x 00 00 00 01,所以在check_sys()函数里直接返回1取地址num,再强制转为char*类型,以便解引用拿到的是1字节的内容,如果c拿到的是01说明是小端,如果c拿到的是00说明是小端。
优点:
C语言提供了一种枚举类型,能够列出所有可能的取值,也叫枚举常量,并给它们取一个名字,关键字是enum,专门来定义枚举类型。
例如:
一周的星期一到星期日是有限的7天,可以一一列举。
性别有:男、女、保密,也可以一一列举。
一年有12个月,也可以一一列举
enum week//枚举类型的声明
{
Mo= 1,//枚举的可能取值
Tues,
Wed,
Th,
Fi,
Sa,
SU,
};
int main()
{
enum Week we = 5;//定义创建变量
printf("%d\n", Sa);
printf("%d\n", Th);
printf("%d\n", Wed);
printf("%d\n", Mo);
printf("%d\n", we);
return 0;
}
创建时里面的内容用逗号隔开。
性质:
这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。
如下打印:
因为枚举的内容是未来可能的取值,要存的是一个值,而这个值是整型的存在,所以大小是4。平台不一样,大小也不一样。
enum Week
{
Mo,
Tues=5,
Wed,
Th,
Fi,
Sa,
SU,
};
int main()
{
printf("%d\n", sizeof(enum Week));
return 0;
}