C语言:自定义类型——联合体和枚举

联合体和枚举

1.联合体类型的声明

1.1联合体类型的声明

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以是不同的类型,联合体的关键字是union

但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间,所以联合体也叫共用体

给联合体其中一个成员赋值,其他成员的值也跟着变化

c 复制代码
#include <stdio.h>
 //联合类型的声明
 
union Un
 {
 	char c;
 	int i;
 };
 int main()
 {
 	//联合变量的定义
	union Un un = {0};
	//计算连个变量的⼤⼩
 
	printf("%d\n", sizeof(un));
	return 0;
}

输出的结果1 4

1.2.联合体的特点

联合的成员是公用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)

代码1输出的三个地址一模一样,代码2的输出我们发现i的第四个字节的内容修改为55了

我们仔细分析就能画出,un的内存布局图

1.3.相同成员的结构体和联合体对比

可以看到,结构体对c和i都开辟了相应的空间,而联合体c和i共用同一块空间

1.4.联合体大小的计算

①:联合体的大小至少是最大成员的大小

②:当最大成员大小不是最大对齐数的整数倍的时候,就要对其到最大对齐数的整数倍

c 复制代码
union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};

int main()
{
	//下⾯输出的结果是什么?

	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
}

使用联合体是可以节省空间的,举例:

比如,我们要搞一个线上的活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书,杯子,衬衫。

每一种商品都有:库存量、价格、商品类型和商品类型相关的其他信息
图书 :书名,作者,页数
杯子 :设计
衬衫:设计,可选颜色,可选尺寸

c 复制代码
struct gift_list
{
    //公共属性
    int stock_number;//库存量
    double price; //定价
    int item_type;//商品类型
    //特殊属性
    char title[20];//书名
    char author[20];//作者
    int num_pages;//⻚数
    char design[30];//设计
    int colors;//颜⾊
    int sizes;//尺⼨
};

上述的结构其实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样会使结构体的大小偏大,比较浪费内存,因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的

比如:

商品是图书,就不需要design,color,sizes

所以我们就可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体联合起来,这样就可以节省所需要的内存空间

c 复制代码
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];//设计
        }mug;
        struct
        {
            char design[30];//设计
            int colors;//颜⾊
            int sizes;//尺⼨
        }shirt;
    }item;
};

1.5.通过联合体判断大小端

c 复制代码
int check_sys()
{
    union
    {
        int i;
        char c;
    }un;
    un.i = 1;
    return un.c;//返回1是⼩端,返回0是⼤端
}

int main()
{
    printf("%d\n", check_sys());
    return 0;
}

2.枚举类型

2.1.枚举类型的声明

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

把可能的取值一一列举

比如生活中:

①:一周的七天可以枚举

②:12个月份可以一一枚举

c 复制代码
enum Day//星期
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};

这就是枚举类型,{}中的内容是枚举类型的可能取值,也叫枚举常量

这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候可以赋初值

2.2.枚举类型的优点

问题 :我们可以使用#define定义常量,为什么要用枚举?
枚举的优点

①:增加代码的可读性和可维护性

②:和#define定义的标识符相比,枚举有类型检查,更加严谨

③:便于调试,预处理阶段会删除#define定义的符号

④:使用方便,一次可以定义多个常量

⑤:枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

相关推荐
寻星探路3 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
lly2024065 小时前
Bootstrap 警告框
开发语言
2601_949146535 小时前
C语言语音通知接口接入教程:如何使用C语言直接调用语音预警API
c语言·开发语言
曹牧5 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
KYGALYX5 小时前
服务异步通信
开发语言·后端·微服务·ruby
zmzb01035 小时前
C++课后习题训练记录Day98
开发语言·c++
爬山算法6 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7256 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎6 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven