介绍位段,枚举和联合

文章探讨了C语言中位段的实现方式,包括如何根据数据类型动态分配内存,以及其在内存分配、类型兼容性和可移植性方面的限制。同时介绍了枚举和联合体的概念,以及它们在内存占用和对齐上的特性。
摘要由CSDN通过智能技术生成

位(二进制位)段就是由结构体来实现的。

位段的成员后有一个冒号和一个数字。位段是一种节省空间的做法。

位段的内存分配

位段的成员可以是 int 、unsigned int 、signed int 或者是 char 等类型。
位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。

也就是说刚开始程序一看是int型的,就给你4个byte位,也就是32个字节,如果说不够,继续4个字节4个字节地开辟

如果一看是char型的就给一个byte位


位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使⽤位段

同时应该注意,冒号后面的数字不能超过其类型的大小。

struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};

首先给char一个byte(第一个byte)位,a用掉3个,还剩5个。b需要4个,b用完还剩下1个,然后c再开辟一个字节(第二个byte位,此时还剩9个字节),轮到c,再开辟1个byte位(第三个byte位)。c用了5个bit,还剩3个bit,d还需要4个,

那么此时是否还需要开辟1个byte位呢?

我们运行程序,计算一下大小,如果是3byte,就证明前面的一个字节被浪费了。

此时我们运算的结果是3,证明前面一个bit被浪费了。

10的二进制数就是1010,但是a只能放三个字节,但是没有关系,能放几个字节就放几个字节,那么就放010吧(假设存放从右向左使用)。12也就是1100,4个bit能够放下。​​​​​​​ 此时剩余一个bit位,按照我们前面的分析,这一个bit位应该被浪费掉。到c这里再开辟一个字节。放3,3的二进制序列也就是011,c是占5个bit位的,我们放5个bit位进去,也就是00011(也就是说,如果位数不够需要补位)。d需要4个bit位,位置不够,再开辟一个字节。​​​​​​​

 

 没有存放的位置就放0。

总共就是3个字节。

结果为8个字节。

位段的跨平台问题

1. int位段被当成有符号数还是⽆符号数是不确定的。
2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最⼤32,写成27,在16位机器会
出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义
4. 当⼀个结构包含两个位段,第⼆个位段成员⽐较大,无法容纳于第⼀个位段剩余的位时,是舍弃
剩余的位还是利用,这是不确定的。

位段使用的注意事项:

 

枚举 

枚举顾名思义就是一一列举。

枚举的结果是012,这表明枚举的结果是依次递增的。

如果在Mon后面加上=1,就可以改变数值: 

那么,在上一个通讯录的文章中我们就可以简化:

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MOD,
	SORT,
};

并且将case 1改为case ADD

枚举常量是不能修改的。枚举类型不是替换的,在调试过程中仍能观察到。

联合体

结果为4,因为大家共用一块空间。联合体也叫作共用体。

当我们打印这三个的地址,竟然一模一样。

大小端判断 

还可以据此判断大小端存储

具体的代码实现如下: 

如下联合体的大小就是8,不能简单地认为联合的大小就是最大成员的大小(而是至少是),这是为什么呢?

当最大成员大小不是最大对齐数的整数倍,就要对齐到最大对齐数的整数倍。

那么,在空间里就是占用了这些空间: 

对齐数是4的倍数,一个14,一个4,那就是16嘛。 

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值