位段的声明和结构体是十分类似的,它们有两个不同之处
int、unsigned int、signed int定义一个名为test的位段
struct test {
int a : 2;
int b : 5;
int c : 10;
int d : 30;
};
00,第一位就是符号,那它只能表示-2~1的数字那么这个位段test的大小是多少?
printf("%d\n", sizeof(struct test));
输出是8,也就是8个字节。
int、unsigned int、signed int、char举个列子,下面这位段是如何开辟内存的呢?
#include
struct test {
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
struct test t = { 0 };
t.a = 10;
t.b = 12;
t.c = 3;
t.d = 4;
printf("%d\n", sizeof(struct test));
return 0;
}
0101100000110100
VS2019调试环境

通过上面的调试发现
前面说过位段的可移植性差,就是因为它的一些不确定因素
这是ipv4首部的一张图,网络传输要保证正确的同时还要保证速度,把每一个字段精确的设计,可以避免没有必要的浪费,就能让数据包尽可能的小,提高传输效率。

联合是一种特殊的自定义类型,它也和结构体类似,也可以包含一系列成员,特征是这些成员共用同一块内存空间,所以叫做联合也可以叫做共用体。
通过union关键字定义一个联合类型
#include
union User
{
int id;
char ch;
};
int main()
{
union User u;
return 0;
}
联合的成员是共用一块内存空间的,这样以一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
来看一段代码
#include
union User
{
int id;
char ch;
};
int main()
{
union User u;
printf("%p\n", &(u.id));
printf("%p\n", &(u.ch));
return 0;
}
打印结果
006FF8B0
006FF8B0
发现这两个成员变量果然用的是同一块内存空间。
再来看一段代码验证一下
#include
union User
{
int id;
char ch;
};
int main()
{
union User u;
u.id = 0x11223344;
u.ch = 0x55;
printf("%x\n", u.id);
return 0;
}
打印结果
11223355
通过联合也可以判断大小端
#include
union User
{
int id;
char ch;
};
int main()
{
union User u;
u.id = 1;
if (u.id)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
来看一个列子
#include
union u1
{
char arr[5];//5
int a;//4
};
union u2
{
short arr[7];//7
int a;//4
};
int main()
{
printf("%d\n", sizeof(union u1));//
printf("%d\n", sizeof(union u2));//
return 0;
}
打印结果
8
16
char arr[5]的对齐数是1联合类型u2
short arr[7],该数组大小是14,它的对齐数是数组中的成员也就是2所以联合的大小至少是最大成员的大小,但不一定是最大成员的大小,还要考虑到最大对齐数对齐
枚举:顾名思义就是一个一个列举。当我们有些类型,不适合用基本类型来,描述的时候就可以使用枚举。
通过enum关键字来定义枚举类型,用枚举来描述一个三原色
enum RGB
{
RED,
GREEN,
BLUE
};
RGB就是自定义的枚举类型,枚举类型的成员是有初始值的,默认从0开始
#include
enum RGB
{
RED,
GREEN,
BLUE
};
int main()
{
printf("%d\n",RED);
printf("%d\n",GREEN);
printf("%d\n",BLUE);
return 0;
}
打印结果
1
2
3
当然也可以修改默认值
#include
enum RGB
{
RED = 10,
GREEN = 15,
BLUE
};
int main()
{
printf("%d\n",RED);
printf("%d\n",GREEN);
printf("%d\n",BLUE);
return 0;
}
打印结果
10
15
16
枚举可以做到事情#define也可以做到,为什么要使用枚举?
枚举的一些优点
#define没有#define一次只能定义一个#define是不能调试的,#define在预编译阶段就把对应的值给替换了#include
enum RGB
{
RED = 10,
GREEN = 15,
BLUE
};
int main()
{
enum RGB color = RED;
printf("%d\n", color);
return 0;
}