当前位置: 首页 > news >正文

C 语言联合与枚举:自定义类型的核心解析

上篇博客中,我们通过学习了解了C语言中一种自定义类型结构体的相关知识,那么该语言中是否还拥有相似的自定义类型呢?这将是我们今天学习的目标。


1.联合体

联合体其实跟结构体类似,也是由一个或多个成员构成,这些成员可以是不同类型。

以下是联合体的定义:

在C语言中,联合体(Union)是一种特殊的数据结构,允许在同一内存位置存储不同的数据类型。


1.1联合体的声明与创建

union un {int n;char ch;
};int main()
{//声明union un u1;union un* pu = &u1;u1.ch = 'w';printf("%c\n", u1.ch);printf("%c\n", pu->ch);u1.n = 5;printf("%d\n", u1.n);printf("%d\n", pu->n);return 0;
}

我们在上面的代码中可以看到,联合体和结构体有非常多类似的地方,创建,声明,访问成员变量都很相似。


 1.2联合体在内存中的存储

编译器在为联合体分配内存时,并不会像结构体一样为每个成员变量都分配内存,它只会分配在内存中占用最大空间的成员变量的空间,其他变量将会于该变量共用这一块空间,所以联合体又叫共用体。所以有一点要注意:给联合体其中一个变量赋值,其他成员的值往往也会跟着变化。

从第一个代码的结果我们可以发现:联合体本身和联合体的成员变量的首个字节地址时相同的。第二个代码我们分别给变量 ic 赋值,发现 i 的结果会被 c 的赋值给覆盖掉,画出它们的内存布局图:


 1.3相同成员的结构体与内存比较

struct S
{char c;int i;
};struct S s = { 0 };union Un
{char c;int i;
};
union Un un = { 0 };

 我们画出它们的内存空间图进行比较:

 我们可以看到,结构体的每个成员都有自己的内存空间,而联合体中 ic 共工用一块空间的。

1.4联合体内存空间大小的计算

 在前面我们说过,编译器只会分配联合体在内存中占用最大空间的成员变量的空间,其实这是不全面的,他还有以下两条规则:

  1. 联合体的大小至少是最大成员的大小
  2. 当最大成员大小不是最大对齐数的整数倍的时候,要对齐到最大对齐数的整数倍。

我们看下面代码:

 第一个联合体un1内部有两个变量,一个是char型数组,一个是 int 类型,计算字符型数组的对齐数时,我们并不会将它的对齐数看作5,而是将其与char类型一样看待,所以他的对齐数是1,而整型类型的对齐数是4,所以un1的对齐数为4,但是该联合体最大成员大小是5,所以该联合体大小为8。

 第一个联合体un2内部也是两个变量,一个是short类型数组,一个是int类型,计算short型数组的对齐数时,也是一样的规则,将其与short类型一样看待,所以他的对齐数是2,而整型类型的对齐数是4,所以un1的对齐数为4,但是该联合体最大成员大小是34,所以该联合体大小为36。

1.5联合体的应用

使用联合体时,因为给它分配的内存空间要少于同样类型结构体,所以使用联合体是要更节省空间的,我们来句一个例子。

我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。 每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。

图书:书名、作者、⻚数

杯⼦:设计

衬衫:设计、可选颜⾊、可选尺⼨

我们不加思索,直接写出结构体:

struct gift_list
{int stock_number;//库存量double price;//价格int item_type;//商品类型char title[20];//书名char author[20];//作者int num_pages;//页数char design[30];//设计int color;//颜色int szie;//尺寸
};

 上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常⽤的。⽐如: 商品是图书,就不需要design、colors、sizes。

所以我们就可以把公共属性单独写出来,剩余属于各种商品本⾝的属性使⽤联合体起来,这样就可以介绍所需的内存空间,⼀定程度上节省了内存。

struct gift_list
{int stock_number;//库存量double price;//价格int item_type;//商品类型union {struct {char title[20];//书名char author[20];//作者int num_pages;//页数}book;struct{char design[30];//设计}cup;struct{char design[30];//设计int color;//颜色int szie;//尺寸}shirt;}item;
};

 下面我们再来做一个熟悉的练习,写一个程序,判断当前机器是大端还是小端?为什么说熟悉呢?因为我们在之前的博客里已经讲过这道题了,之前我们时这样做的:

int main()
{int n = 1;int* ps = &n;if (*((char*)ps) == 1)printf("小端");elseprintf("大端");return 0;
}

之前我们是用了强制转换来这道题的,学习了联合体后,我们有没有其他的思路呢?看下面代码:

union
{int i;char c;
}un;int main()
{un.i = 1;if (un.i == 1)printf("小端");elseprintf("大端");return 0;
}

这个代码利用了联合体内变量共用同一块内存,如果是小端存储模式,将i赋值为1,那么c也会被赋值为1,如果没有,则证明是大端存储模式。 

 2.枚举类型

2.1枚举变量的声明

枚举顾名思义就是⼀⼀列举。
把可能的取值⼀⼀列举。
⽐如我们现实⽣活中:
⼀周的星期⼀到星期⽇是有限的7天,可以⼀⼀列举
性别有:男、⼥、保密,也可以⼀⼀列举
⽉份有12个⽉,也可以⼀⼀列举
三原⾊,也是可以意义列举
这些数据的表⽰就可以使⽤枚举了。
enum Month
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};enum Sex
{male,female,secret,
};enum Color
{red,green,blue
};
以上定义的 enum Day enum Sex enum Color 都是枚举类型。
{}中的内容是枚举类型的可能取值,也叫 枚举常量 。
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。
//默认
enum Color
{red = 0,green = 1,blue = 2
};enum Color
{red = 1,green = 5,blue = 9
};

2.2枚举变量的优点

我们可以使⽤ #define 定义常量,为什么⾮要使⽤枚举?
枚举的优点:
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。
3. 便于调试,预处理阶段会删除 #define 定义的符号
4. 使⽤⽅便,⼀次可以定义多个常量
5. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤

2.3枚举的使用 

enum Color//颜⾊
{RED=1,GREEN=2,BLUE=4
};
enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值
那是否可以拿整数给枚举变量赋值呢?在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查⽐较严格。

相关文章:

  • [Swift]Xcode模拟器无法请求http接口问题
  • Qt unknown module(s) in qt:serialport解决方法
  • Oracle Recovery Tools修复ORA-600 6101/kdxlin:psno out of range故障
  • C++11新增语法:列表初始化
  • 实现AWS Lambda函数安全地请求企业内部API返回数据
  • [每周一更]-(第140期):sync.Pool 使用详解:性能优化的利器
  • Python制作简易PDF查看工具PDFViewerV1.0查找功能优化
  • 【文件操作与IO】详细解析文件操作与IO (二)
  • 零、HarmonyOS应用开发者基础学习总览
  • Cursor新版0.49.x发布
  • 开源Midjourney替代方案:企业级AI绘画+PPT生成系统+AI源码
  • YOLO拓展-锚框(anchor box)详解
  • 深入理解C++ 中的vector容器
  • 机器学习核心算法全解析:从基础到进阶的 18 大算法模型
  • 点云数据处理开源C++方案
  • 神经网络的数学之旅:从输入到反向传播
  • 在串口通信中使用共享指针(`std::shared_ptr`)
  • 用 R 语言打造交互式叙事地图:讲述黄河源区生态变化的故事
  • MCP认证难题破解:常见技术难题实战分析与解决方案
  • 额外篇 非递归之美:归并排序与快速排序的创新实现
  • 鲁比奥称“美或退出俄乌谈判”,欧洲官员:为了施压乌克兰
  • 老年人越“懒”越健康,特别是这5种“懒”
  • 中签不易,住宿更难,马拉松赛事期间酒店涨价难题如何解决?
  • 卡洛·金茨堡:女巫与萨满——我的学术之路
  • 谁在向张福生行贿?
  • 9部门发文促进家政服务消费扩容升级