C语言 联合和枚举

目录

  • 1. 联合体
    • 1.1 联合体类型的声明
    • 1.2 联合体变量的创建
    • 1.3 联合体的特点
    • 1.4 联合体在内存中的存储
    • 1.5 联合体使用举例
  • 2. 枚举类型
    • 2.1 枚举类型的声明
    • 2.2 枚举变量的创建和初始化
    • 2.3 枚举类型的大小
    • 2.4 枚举类型的优点


正文开始

上次我们通过《C语言 结构体详解》学习了结构体的相关知识,今天我们来学习一下结构体的亲戚联合枚举,它们同结构体一样,都是C语言中的自定义类型,由一个或多个成员构成。因为本文所讲内容与结构体有很多相似之处,所以先学习结构体再食用本文更佳呦~

1. 联合体

1.1 联合体类型的声明

联合体的声明和结构体的声明类似:

union Un_name
{member-list;
};

其中:

  • union用来声明这是一个联合体
  • Un_name是联合体名
  • member-list为成员列表

1.2 联合体变量的创建

#include <stdio.h>//联合体类型的声明
union Un
{char c;int i;
};int main()
{//联合变量的定义union Un un = { 0 };un.i = 3;un.c = 'a';return 0;
}

联合体变量的创建以及初始化等与结构体基本相同,这里不再赘述。

1.3 联合体的特点

联合体的声明与结构体基本相同,那两者有什么区别呢?我们都知道结构体在内存中的存储符合内存对齐规则,这样做的好处就是增强了性能,但是却浪费了空间。而联合体主打一个节省空间,原因如下:

  • 联合体成员共用一块内存(所以联合体又叫共用体)
  • 联合体大小至少为最大成员的大小,这样才能确保能放下所有数据

我们写个代码验证一下:

# include <stdio.h>union Un
{char c;int i;
};int main()
{union Un un = { 0 };printf("%p\n", &(un.c));printf("%p\n", &(un.i));printf("%p\n", &un);return 0;
}

运行结果:
在这里插入图片描述
由此我们验证了,联合体成员共用一块内存。

1.4 联合体在内存中的存储

联合体成员共用一块内存,那他们究竟是怎么存储的呢?

  • 联合体的大小至少是最大成员的大小
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍
  • 由于联合体成员共用同一块内存,所以一般独立使用各个联合体成员

例如:

#include <stdio.h>union Un1
{char c[5];int i;
};union Un2
{short c[7];int i;
};int main()
{printf("Un1 -> %zd\n", sizeof(union Un1));printf("Un2 -> %zd\n", sizeof(union Un2));return 0;
}

在内存中的存储情况如下:
在这里插入图片描述

上图可以看出,整个联合体的大小满足两个条件:

  • 至少是最大成员的大小
  • 大小要对齐到最大对齐数的整数倍。例如 Un1 最大的对齐数是4,所以总大小补齐为8;Un2 最大的对齐数是4,所以总大小补齐为16

运行验证一下:
在这里插入图片描述

1.5 联合体使用举例

假如我们需要记录图书、杯子、衬衫三种商品的数据,每一种商品都有:库存量、价格、商品类型和一些其他信息:

  • 图书:书名、作者、页数
  • 杯子:设计
  • 衬衫:设计、颜色、尺寸

如果我们使用结构体书写:

struct Product
{//共有属性int stock_number;//库存量double price;//价格int item_type;//商品类型//特有属性char title[20];//书名char author[20];//作者int num_page;//页数char design[30];//设计int colors;//颜色int sizes;//尺寸
};

这样写似乎没有什么问题,但一个结构中包含了所有商品的各种属性,当我们描述图书的时候,就用不上设计、颜色和设计,这样就使得结构体的大小偏大,比较浪费内存。所以我们可以使用联合体书写:

struct Product
{//共有属性int stock_number;//库存量double price;//价格int item_type;//商品类型union{struct{char title[20];//书名char author[20];//作者int num_page;//页数}book;//图书struct{char design[30];//设计}mug;//杯子struct{char design[30];//设计int colors;//颜色int sizes;//尺寸}shirt;//衬衫}item;
};

这样就相当于把三种商品的特有属性共存在一块内存中,使用时也相互独立,这样保证了正常使用,也能够节省空间。

2. 枚举类型

枚举,顾名思义就是一个一个列举,比如我们现实生活中:

  • 星期一到定期日可以列举
  • 性别可以列举
  • 月份可以列举

2.1 枚举类型的声明

枚举类型的声明与结构体类似:

enum Enum_name
{value1,value2,value3,//...
};
  • 使用关键字enum来声明枚举类型
  • Enum_name为枚举名
  • {}中的内容为枚举类型的可能取值,称作枚举常量。
  • 枚举常量之间由,隔开
  • 枚举常量都是有初始值的,默认从0开始,步长为1依次递增。
  • 给定枚举常量的值,就类似于#define定义标识符,只不过#define是在预处理阶段完成的,枚举类型是在编译阶段完成的

例如:

enum Color
{RED,//0GREEN,//1BLUE//2
};

我们也在声明枚举类型时赋值:

enum Color1
{RED=3,//3GREEN,//4BLUE//5
};enum Color2
{RED=3,//3GREEN=5,//5BLUE=7//7
};enum Color3
{RED,//0GREEN=3,//3BLUE//4
};

对于枚举类型的理解:
声明一个枚举,就是定义了一种类型,这种类型的可能取值就是枚举常量的值

2.2 枚举变量的创建和初始化

枚举变量的创建和初始化与结构体类似,这里只做演示,详情不再赘述。

enum Color
{RED,//0GREEN,//1BLUE//2
};int main()
{enum Color red = 0;//等同于RED//定义了一个类型为 enum Color 的枚举变量red//变量 red 的值为0,也就是REDreturn 0;
}

2.3 枚举类型的大小

枚举是一种数据类型,它的可能取值就使枚举常量的值,枚举常量本质都是整型,也就是说,不管是枚举类型,还是枚举变量,亦或是枚举常量,它们的大小都与整型相同,都是4个字节,下面我们验证一下:

#include <stdio.h>enum Color
{RED,GREEN,BLUE
};int main()
{enum Color red;printf("%d\n", sizeof(enum Color));//枚举类型printf("%d\n", sizeof(RED));//枚举常量printf("%d\n", sizeof(GREEN));//枚举常量printf("%d\n", sizeof(BLUE));//枚举常量printf("%d\n", sizeof(red));//枚举变量return 0;
}

运行结果:
在这里插入图片描述

2.4 枚举类型的优点

有的人可能会想到,既然都是定义常量,那为什么不用#define呢?

因为枚举有以下优点:

  • 枚举将标识符集中起来,不像是#define那样分散开,增加了代码的可读性和可维护性
  • 枚举类型定义的标识符有类型检查(是枚举类型),更为严谨,而#define没有(直接替换)
  • 便与调试,预处理阶段会删除#define定义的符号
  • 使用方便,一次可以定义多个常量
  • 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用,而#define定义的标识符是全部都直接替换


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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试 - 字符串消除 - 栈Stack(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

论文辅助笔记:Tempo 之 model.py

0 导入库 import math from dataclasses import dataclass, asdictimport torch import torch.nn as nnfrom src.modules.transformer import Block from src.modules.prompt import Prompt from src.modules.utils import (FlattenHead,PoolingHead,RevIN, )1TEMPOConfig 1.…

【模型参数优化】随机搜索对随机森林分类模型进行参数寻优【附python实现代码】

写在前面&#xff1a; 首先感谢兄弟们的订阅&#xff0c;让我有创作的动力&#xff0c;在创作过程我会尽最大能力&#xff0c;保证作品的质量&#xff0c;如果有问题&#xff0c;可以私信我&#xff0c;让我们携手共进&#xff0c;共创辉煌。 路虽远&#xff0c;行则将至&#…

苍穹外卖项目

Day01 收获 补习git Git学习之路-CSDN博客 nginx 作用&#xff1a;反向代理和负载均衡 swagger Swagger 与 Yapi Swagger&#xff1a; 可以自动的帮助开发人员生成接口文档&#xff0c;并对接口进行测试。 项目接口文档网址&#xff1a; ​​​​​​​http://localhost:808…

上位机图像处理和嵌入式模块部署(树莓派4b部署java环境)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 通常我们都会认为java是部署在pc服务器上面的&#xff0c;或者是用java开发android应用程序。其实不然&#xff0c;java也可以部署在嵌入式开发板子…

这是一个简单的照明材料网站,后续还会更新

1、首页效果图 代码 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>爱德照明网站首页</title><style>/*外部样式*/charset "utf-8";*{margin: 0;padding: 0;box-sizing: border-box;}a{text-dec…

SVM直观理解

https://tangshusen.me/2018/10/27/SVM/ https://www.bilibili.com/video/BV16T4y1y7qj/?spm_id_from333.337.search-card.all.click&vd_source8272bd48fee17396a4a1746c256ab0ae SVM是什么? 先来看看维基百科上对SVM的定义: 支持向量机&#xff08;英语&#xff1a;su…

JVM笔记1--Java内存区域

1、运行时数据区域 从上图可以看出来&#xff0c;Java虚拟机运行时数据区域整体上可以分成5大块&#xff1a; 1.1、程序计数器 程序计数器是一块较小的内存空间。它可以看做当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里&#xff0c;字节码解释器工作时就是…

工厂流水线生产视频素材哪里有?工厂固定机位视频素材从哪找?

在当今这个视觉内容至关重要的数字时代&#xff0c;具备高质量视频素材的资源库是制胜关键。优质视频素材不仅能够显著提升品牌的视觉吸引力&#xff0c;还能帮助你在社交媒体上获得更多的关注和互动。下面介绍的视频素材网站&#xff0c;每一个都能为你的视频项目提供必要的视…

【Python】机器学习之Sklearn基础教程大纲

机器学习之Sklearn基础教程大纲 1. 引言 机器学习简介Scikit-learn&#xff08;Sklearn&#xff09;库介绍安装和配置Sklearn 2. 数据预处理 2.1 数据加载与查看 - 加载CSV、Excel等格式的数据- 查看数据的基本信息&#xff08;如形状、数据类型等&#xff09;2.2 数据清洗…

深入浅出 BERT

Transformer 用于学习句子中的长距离依赖关系&#xff0c;同时执行序列到序列的建模。 它通过解决可变长度输入、并行化、梯度消失或爆炸、数据规模巨大等问题&#xff0c;比其他模型表现更好。使用的注意力机制是神经架构的一部分&#xff0c;使其能够动态突出显示输入数据的…

Git系列:如何为不同的Git仓库设置不同的配置项?

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

威尔科克森秩和检验 (Wilcoxon rank-sum test)-- 代码实现

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

阿里低代码引擎学习记录

官网 一、关于设计器 1、从设计器入手进行低代码开发 设计器就是我们用拖拉拽的方法&#xff0c;配合少量代码进行页面或者应用开发的在线工具。 阿里官方提供了以下八个不同类型的设计器Demo&#xff1a; 综合场景Demo&#xff08;各项能力相对完整&#xff0c;使用Fusion…

深度学习之基于Unet肺部CT图像分割项目

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 肺部CT图像分割在医学诊断中占据重要地位&#xff0c;它有助于医生快速、准确地识别和分析肺部病变。…

【数据库原理及应用】期末复习汇总高校期末真题试卷

试卷 一、填空题 1.________是位于用户与操作系统之间的一层数据管理软件。 2.数据库系统的三级模式结构是指________、________、________。 3.数据库系统的三种数据模型是________ 、________、________。 4.若关系中的某一属性组的值能唯一地标识一个元组&#xff0c;则…

2024-第四批C++ 第二轮选拔赛(代码加解析)

第二轮比赛结束了&#xff0c;答案又出来了&#xff0c;充实的一天又过去了...... 一、摘苹果 题目描述 小白同学种植了一颗苹果树&#xff0c;经过他悉心的照料&#xff0c;苹果树终于结果了&#xff0c;结出了很多苹果。 现在树上有 n 个苹果&#xff0c;因为体力有限&…

【matlab基础知识】(二)

i从1加到100 >> s10;for i1:100,s1s1i;end;s1 s1 5050 >> s20;i1;while(i<100),s2s2i;ii1;end;s2 s2 5050 >> sum(1:100) ans 5050 >> s10;m0;while(s1<10000),mm1;s1s1m;end;s1,m s1 10011 m 141 tic, s0;for i1:100000,ss1/2^i1/3…

【kettle006】kettle访问华为openGauss高斯数据库并处理数据至execl文件(已更新)

1.一直以来想写下基于kettle的系列文章&#xff0c;作为较火的数据ETL工具&#xff0c;也是日常项目开发中常用的一款工具&#xff0c;最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下华为openGauss高斯数据库相关知识体系 3.欢迎批评指正&#xff0c;跪谢…

在VMware虚拟机ubuntu中运行usb_cam.launch时出现报错出现报错:select timeout

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、运行usb_cam.launch时出现报错出现报错&#xff1a;select timeout1.问题描述2.问题解决 一、运行usb_cam.launch时出现报错出现报错&#xff1a;select timeou…