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定义的符号

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

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

相关推荐
后端AI实验室4 小时前
我把一个生产Bug的排查过程,交给AI处理——20分钟后我关掉了它
java·ai
凉年技术6 小时前
Java 实现企业微信扫码登录
java·企业微信
狂奔小菜鸡7 小时前
Day41 | Java中的锁分类
java·后端·java ee
hooknum7 小时前
学习记录:基于JWT简单实现登录认证功能-demo
java
程序员Terry8 小时前
同事被深拷贝坑了3小时,我教他原型模式的正确打开方式
java·设计模式
NE_STOP8 小时前
MyBatis-缓存与注解式开发
java
码路飞8 小时前
不装 OpenClaw,我用 30 行 Python 搞了个 QQ AI 机器人
java
Re_zero8 小时前
以为用了 try-with-resources 就稳了?这三个底层漏洞让TCP双向通讯直接卡死
java·后端
SimonKing8 小时前
Fiddler抓包完全指南:从安装配置到抓包,一文讲透
java·后端·程序员
磊磊落落10 小时前
如何将 Spring Statemachine 作为一个轻量级工作流引擎来使用?
java