C语言自定义类型【联合体与枚举】

文章目录

  • 1.联合体
    • 1.1联合体的声明
    • 1.2联合体的特点
    • 1.3联合体的大小计算
      • 联合体的使用案例
  • 2.枚举
    • 2.1枚举类型的声明
    • 2.2枚举类型的优点(为什么使用枚举)
    • 2.3枚举类型的使用
  • 结语

1.联合体

1.1联合体的声明

和结构体一样,联合体也是由一个或多个成员构成,同样,这些成员也可以是不同的类型。
但是,编译器只会为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以,联合体也叫共用体

#include<stdio.h>
//联合体的声明
union Un
{char c1;int i;char c2;
};int main()
{//创建一个union Un类型的临时变量union Un un = { 0 };//计算联合体变量的大小printf("union Un 大小为%zd", sizeof(un));return 0;
}

在这里插入图片描述

为什么是4呢?
我们就来了解联合体的特点吧

1.2联合体的特点

联合的成员是共用同一块内存空间,所以一个联合体变量的大小至少是最大成员的大小(因为联合至少得有能力存放最大的成员)。

#include<stdio.h>
//联合体的声明
union Un
{char c1;int i;
};int main()
{//创建一个union Un类型的临时变量union Un un = { 0 };//查看联合成员的地址printf("成员i 的地址为  %p\n", &un.i);printf("成员c1的地址为  %p\n", &un.c1);printf("联合体un的地址为%p\n", &un.c1);return 0;
}

在这里插入图片描述
可以看到输出的三个地址一模一样。

#include<stdio.h>//联合体的声明
union Un
{char c1;int i;
};int main()
{//创建一个union Un类型的临时变量union Un un = { 0 };un.i = 0x11223344;un.c1 = 0x55;//查看联合体成员的值(16进制)printf("成员i的为%x\n", un.i);return 0;
}

在这里插入图片描述

在这里插入图片描述
我们通过调试可以看到,i的第4个字节的内容被修改为了55。
在这里插入图片描述
在这里插入图片描述
这又证明了,联合体的所有成员是共用同一块空间。

成员相同的结构体和联合体进行比较

#include<stdio.h>struct Str
{char c1;int i1;
};union Un
{char c2;int i2;
};int main()
{printf("struct Str的大小为%zd\n", sizeof(struct Str));printf("union Un的大小为%3zd", sizeof(union Un));return 0;
}

在这里插入图片描述
他们的成员大小相同,成员顺序相同,但输出的结果还是不同,也就是说结构体和联合体对待成员的存放是不同的。
结构体每个成员有独立的空间,而联合体是共用一块空间

1.3联合体的大小计算

1.联合体的大小至少是最大成员的大小
2.如果最大成员的大小不是最大对齐数的整数倍时,空间大小要对齐到最大对齐数的整数倍
看代码:

union Un1//最大对齐数为4(int)
{char ch[5];//大小为5(最大)int i;//大小为4
};union Un2//最大对齐数为4(int)
{short sh[5];//大小为10(最大)int i;//大小为4
};union Un3//最大对齐数为8(long long)
{int arr[5];//大小为20(最大)long long lg;//大小为8
};int main()
{printf("union Un1的大小为%zd\n", sizeof(union Un1));printf("union Un2的大小为%zd\n", sizeof(union Un2));printf("union Un3的大小为%zd\n", sizeof(union Un3));return 0;
}

在这里插入图片描述

联合体的使用案例

联合体的使用案例
假如我们要搞⼀个活动,要上线⼀个礼品兑换单
礼品兑换单中有三种商品:图书、杯⼦、衬衫。
每种商品都有:库存,价格,商品类型,我们称之为公共属性
其中每个商品有各自的特殊属性
图书:书名,作者,页数
杯子:设计方案
衬衫:设计方案,颜色,尺寸

解决方法一:

struct gift_list
{//公共属性int stock_number;//库存double price;//价格int item_type;//商品类型//特殊属性char Title[20];//书名char Author[20];//作者int Num_page;//页数char Design;//设计方案(杯子和衬衫都有设计方案)char Colors[10];//颜色int Size;//尺寸};

上面的的代码,很暴力,也很方便,但是结构的设计中包含了所有礼物的属性,这样会使得结构体的大小会偏大,比较浪费空间。而且对于单个商品来说,只有部分属性是我要用的。

比如商品是衬衫的话我要用的就是Design、Colors、Size,而Title、Author、Num_page就是不需要的属性

所有我们可以把公共属性独立写出来,剩余各种商品本身的特殊属性就可以使用联合体。这样就可以在一定程度上节省空间。

struct Gift_List
{//公共属性int stock_number;//库存double price;//价格int item_type;//商品类型union MyUnion{struct{char Title[20];//书名char Author[20];//作者int Num_page;//页数}book;struct {char Design;//设计方案(杯子和衬衫都有设计方案)}mug;struct {char Design;//设计方案(杯子和衬衫都有设计方案)char Colors[10];//颜色int Size;//尺寸}shirt;}item;
};

2.枚举

2.1枚举类型的声明

顾名思义就是将可能的元素进行一一列举
例如我们生活中的:一周的星期一到星期日、十二个月份、三原色;这些都可以一一列举
附上代码

enum Colors//
{RED,BLUE,GREEN
};enum Week_By_Day
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};

以上定义的 颜色一周都是枚举类型。
而{}里的内容是枚举类型里的可能取值,这也叫做枚举常量。

这些可能取值都是有值的(创建常量的时候肯定是要赋值的)
枚举常量默认从0开始,依次递增1,当然,在声明枚举类型的时候也可以赋初始值。

enum Direction
{NORTH,//初始值在没有赋值的情况下就是0//后面的值发生改变也不会改变前面的值EAST,WEST = 5,SOUTH
};int main()
{printf("%d\n", NORTH);printf("%d\n", EAST);printf("%d\n", WEST);printf("%d\n", SOUTH);return 0;
}

在这里插入图片描述
初始值在没有赋值的情况下就是0,后面的值发生改变也不会改变前面的值

2.2枚举类型的优点(为什么使用枚举)

明明我们有#define 来定义常量,为什么要使用枚举?

1.增加代码的可读性和可维护性
2.和#define定义的标识符进行比较,枚举有类型检查,更加严谨
3.便于调试,预处理阶段会直接将#define定义的符号替换为原来的符号
4.使用更方便,一次可以定义多个常量
5.枚举常量是遵循作用域规则的,枚举声明在某个函数内,只能在该函数内部使用

2.3枚举类型的使用

#include<stdio.h>
enum Colors
{RED,//0BLUE,//1GREEN//2
};
int main()
{enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值printf("clr的值为%d", clr);return 0;
}

在这里插入图片描述

补充:
那我们是否可以拿整数给枚举变量赋值呢?在C语言中是可以的,但是在C++是不行的,C++的类型检查比较严格。

结语

最后感谢您能阅读完此片文章,如果有任何建议或纠正欢迎在评论区留言。如果您认为这篇文章对您有所收获,点一个小小的赞就是我创作的巨大动力,谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/314955.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker数据管理与Dockerfile镜像创建

前言 在容器化环境中&#xff0c;如何有效地管理和持久化数据成为了开发人员和运维团队面临的挑战之一&#xff1b;另一方面&#xff0c;镜像的创建是构建容器化应用的基础。优化的镜像设计可以提高部署效率和应用性能&#xff0c;减少资源消耗和运行成本。本文将介绍 Docker …

Java 解决pdfbox转图片显示中文乱码 No glyph for 165 (CID 5752) in font STSong-Light

问题描述&#xff1a; 在开发PDF转JPG图片后&#xff0c;图片显示中文乱码&#xff0c;以下为具体示例&#xff1a; pdf源文件&#xff1a; 转换成JPG后&#xff1a; 截图可以看到&#xffe5;符号无法转换为乱码 关键代码报错截图&#xff1a; 代码已经提示我们STSong-Light字…

IDEA 编码规约扫描 Code inspection did not find anything to report.

IDEA安装了Alibaba Java Coding Guidelines插件&#xff0c;却看不到规约检查结果。手动进行编码规约扫描&#xff0c;弹窗提示“Code inspection did not find anything to report.”&#xff1a; 这种情况是因为代码文件所在的目录被标记成了测试文件&#xff08;Test Source…

[leetcode] B树是不是A树的子结构

给定两棵二叉树 tree1 和 tree2&#xff0c;判断 tree2 是否以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。 注意&#xff0c;空树 不会是以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。 示例 1&#xff1a; 输入&#xff1a;tree1 [1,7,5], tree2 [6,…

ansible-copy用法

目录 概述实践不带目录拷贝带目录拷贝 概述 ansible copy 常用用法举例 不带目录拷贝&#xff0c;拷贝的地址要写全 带目录拷贝&#xff0c;拷贝路径不要写在 dest 路径中 实践 不带目录拷贝 # with_fileglob 是 Ansible 中的一个循环关键字&#xff0c;用于处理文件通配符匹…

docker 基本命令

目录 一、docker 镜像操作命令 1.1.查询软件镜像 1.2.docker pull&#xff1a;下载镜像 1.3.docker push&#xff1a;上传镜像 1.4.docker images&#xff1a;查看本地镜像 1.5.docker inspect &#xff1a;获取镜像详细信息 1.6.docker tag&#xff1a;添加镜像标签 …

【vscode】2024最新!vscode云端配置同步方案:code settings sync

小tian最近对电脑进行了系统重装&#xff0c;结果vscode相关配置和插件都没有保存记录&#xff0c;还好公司电脑里还有。痛定思痛&#xff0c;决定写一篇vscode云端同步配置方案&#xff0c;以作记录和分享~ 步骤一&#xff1a;安装vscode插件&#xff1a;code settings sync …

基于SpringBoot + Vue实现的家政服务管理系统设计与实现+毕业论文+答辩PPT+指导搭建视频(包运行成功)

目录 项目介绍 论文展示 资源获取 项目介绍 家政服务管理平台是一个管理信息系统&#xff0c;为了宣传的需要&#xff0c;为了给用户提供方便快捷的服务&#xff0c;从而设计了家政服务管理平台。管理员可以通过这个系统把家政服务信息发布出去&#xff0c;可以方便用户快…

Mac下使用homebrew管理多版本mysql同时启动

Mac下使用homebrew管理多版本mysql同时启动 思路 给每个版本分配不同的数据目录和配置文件即可 本文尝试了使用 brew 安装管理多个MySQL版本&#xff0c;同时运行、直接切换 安装 如果已有数据文件请自行备份以及使用 安装 mysql 5.7 brew install mysql5.7在 /opt/home…

微信小程序使用echarts实现条形统计图功能

微信小程序使用echarts组件实现条形统计图功能 使用echarts实现在微信小程序中统计图的功能&#xff0c;其实很简单&#xff0c;只需要简单的两步就可以实现啦&#xff0c;具体思路如下&#xff1a; 引入echarts组件调用相应的函数方法 由于需要引入echarts组件&#xff0c;代…

Vue2学习笔记(尚硅谷天禹老师)

目录 一、入门案例 二、模板语法 三、数据绑定 四、el和data的两种写法 五、MVVM模型 六、Object.defineproperty方法 七、Vue中响应式原理 八、数据代理 九、methods配置项 十、Vue中的事件处理 十一、Vue中的键盘事件 十二、计算属性 十三、监视属性watch 十四、绑定Class样式…

深入理解操作系统与计算机体系结构

文章目录 操作系统(Operator System)为什么要有操作系统操作系统是如何进行管理的为什么说操作系统是安全&#xff0c;稳定&#xff0c;高效的理解系统调用和库函数 操作系统(Operator System) 概念&#xff1a; 操作系统&#xff08;Operating System&#xff0c;简称OS&…

会跳舞的网站引导页HTML源码

源码介绍 这套引导页源码非常好看&#xff0c;网址也不会不停的动起来给人一种视觉感很强烈 简单修改一下里面的地址就行看&#xff0c;非常简单&#xff01; 效果预览 源码下载 会跳舞的网站引导页HTML源码

数据结构——插入排序

基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。 实际中我们玩扑克牌时&…

视频通话实时换脸:支持训练面部模型 | 开源日报 No.235

iperov/DeepFaceLive Stars: 19.7k License: GPL-3.0 DeepFaceLive 是一个用于 PC 实时流媒体或视频通话的人脸换装工具。 可以使用训练好的人脸模型从网络摄像头或视频中交换面部。提供多个公共面部模型&#xff0c;包括 Keanu Reeves、Mr. Bean 等。支持自己训练面部模型以…

图像处理到神经网络:线性代数的跨领域应用探索

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

Maven解决找不到依赖项

报错如图 方案一&#xff1a;Maven的Setting文件中添加albaba的镜像文件 1.下载maven &#xff1a;Maven – Download Apache Maven 2. 配置镜像 更改成这个&#xff1a; <mirror> <id>alimaven</id> <name>aliyun maven</name> <url&g…

Rust腐蚀服务器搭建架设教程ubuntu系统

Rust腐蚀服务器搭建架设教程ubuntu系统 大家好我是艾西一个做服务器租用的网络架构师。Rust腐蚀游戏对于服务器的配置有一定的要求很多小伙伴就思考用linux系统搭建的话占用会不会小一点&#xff0c;有一定电脑基础的小伙伴都知道Linux系统和windows系统相比较linux因为是面板…

短视频生成背景文字工具(前端工具)

过年这两天有些无聊就刷刷抖音&#xff0c;刷着刷着自己也蠢蠢欲动&#xff0c;想发上几个&#xff0c;可是却找不到合适自己的模板。由于个人喜欢一些古诗文之类的&#xff0c;所以自己简单的编写了一个小工具&#xff0c;如下图&#xff1a; 当设置好了之后&#xff0c;将浏…

小程序线多点路图绘制

需求 当接口返回一连串地图坐标&#xff0c;需要根据这些坐标串联起来&#xff0c;形成一个线路图&#xff08;本次使用步行导航线路图&#xff09;。 思路 首先优先想到使用小程序Map组件的polyline属性去进行展示。但是我们发现直接使用该属性进行坐标绘制画出来的数据都是…