🎬 鸽芷咕:个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》
⛺️生活的理想,就是为了理想的生活!
🌈hello! 各位宝子们大家好啊,前面一章给大家带来了结构体的深层次 讲解,那么接下来就来到下一章的学习了,铁铁们准备好了嘛? ⛳️本期给大家带来的是 位段的内存分配 枚举 联合(共用体)的详细讲解让我们一起学起来把! 📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐! ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!
⛳️一般情况下在书里,结构体的章节过来了之后就是位段(位域)叫法不同而已,说明我们的位段是靠结构体来实现的!
位段的声明和结构是类似的,有两个不同:
。
📚 代码演示:
struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};
⛳️ 这里A就是一个位段类型。那位段A的大小是多少?
📑 代码结果:
诶这时你会发现这个结构体的内存对齐计算结构体大小完全不一样啊!为什么大小是这个呢?
🔥 注:结构体如何计算大小文章链接《结构体的内存对齐》
⛳️ 位段位段,说明他是位的截段 那么是什么位呢?答案是
比特位
!,每个数字是占多少个比特位
!
比特位
4
个字节刚好能装下struct B
{
int _a : 2;
int _b : 5;
int _c : 15;
int _d : 10;
};
📑 代码结果:
哦!的确是这样的。下面我们就来具体看下位段到底是怎么样开辟空间的
📜说明:
int
unsigned int
signed int
或者是 char
(属于整形家族)类型4
个字节( int
)或者1个字节( char
)的方式来 开辟 的。⛳️ 这些是什么意思呢?就是我们位段的成员必须是整形家族的,如果我们位段时int 类型的那么就会先开辟4个字节,不够在开辟4个字节这样一直开辟下去, char类型的也是同理!
📚 举个例子:
#include <stdio.h>
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;
}
⛳️那么究竟是不是我们这样描述存储的实践一下看看就明白了,假设我们在vs2019 这个平台上是从低向高访问的
这里我们想象的大致内存分布是这样的,用了3个字节,程序运行看下是不是这样的?
📑 代码结果:
哦!看来在vs这个环境里就是按我们想像的这样开辟空间的我们在验证一下
比特位
存放位段成员 a
在内存中占3个字节但是 10
这个数字要存放 4
个字节,所以我们就会截断
10
的二进制位是1010a
存放的就是010
✅ 我们把存放进去的二进制位转成16进制来看一下!
16进制
所以 4
个比特位 为一个 16进制
!
⛳️这里就可以看到按我们这存放的话,转换出来的16进制是 0x 62 03 04 00
📑图片展示:
这时就可以看出在vs2019就是按我们想的那样存储的!
注:但是在C语言中从左向右分配,还是从右向左分配标准尚未定义!
注:当第一个位段的剩余的内容无法存储第二个位段时,要开辟新的空间,那之前剩余的空间是否被利用取决于平台,也没有规定.
⛳️ 跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
枚举顾名思义就是一一列举。 把可能的取值一一列举。 比如我们现实生活中:
一周的星期一到星期日是有限的7天,可以一一列举。 性别有:男、女、保密,也可以一一列举。 月份有12个月,也可以一一列举
这里就可以使用枚举了。
⛳️ 那么我们怎么定义枚举类型呢?其实和结构体差不多
📚 代码演示:
enum Color//颜色
{
RED,
GREEN,
BLUE
};
{ }
中的内容是枚举类型的可能取值,也叫 枚举常量 。📚 代码演示:
#include <stdio.h>
enum Color//颜色
{
RED = 1,
GREEN = 9,
BLUE = 4
};
int main()
{
printf("%d", RED);
printf("%d", GREEN);
printf("%d", BLUE );
return 0;
}
📑 代码结果:
我们可以使用 #define 定义常量,为什么非要使用枚举?
📜枚举的优点:
#define
定义的标识符比较枚举有类型检查,更加严谨。⛳️ 和
#define
定义的标识符比较枚举有类型检查,更加严谨。
📚 代码演示:
#include <stdio.h>
enum Color//颜色
{
RED = 1,
GREEN = 2,
BLUE = 4
};
int main()
{
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值
return 0;
}
⛳️联合也是一种特殊的自定义类型 ⛳️这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
union
⛳️ 那么我们如何定义联合体呢?下面就来看一下假如来定义一个un 联合体
📚 代码演示:
#include <stdio.h>
union un
{
char c;
int i;
};
int main()
{
printf("%d", sizeof(un));
return 0;
}
📑 代码结果:
啊!这里就有许多铁汁们要问了,一个
int
一个char
怎么也得5个字节,而这里才用了4个字节!
⛳️联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
📑图片展示:
✅ 举个例子:
#include <stdio.h>
union un
{
char c;
int i;
};
int main()
{
union un un = { 0 };
// 下面输出的结果是一样的吗?
printf("%p\n", &(un.i));
printf("%p\n", &(un.c));
//下面输出的结果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
return 0;
}
有人就会问了,既然我们是公用一块内存的那么先把
i
里面放满内容。然后 使用c
变量i
会改变嘛?
📑 代码结果:
哦~!看来的确是像我们前面画的那样存储的!
🔰 是不是非常简单,下面我们就留俩个例题给大家练习练习!
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
//下面输出的结果是什么?
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));
✅ 归纳:
好了以上就是关于 位段
枚举
联合
就全部讲解完毕啦!
位段的内存分配
位段的跨平台问题
枚举类型的定义
枚举的优点
联合大小的计算
☁️ 好了把这些知识点全部掌握就可以彻底搞懂, 位段
枚举
联合
啦!快去试试吧
看到这里了还不给博主扣个:
⛳️ 点赞
☀️收藏
⭐️ 关注
!
💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。