【C语言】自定义类型:联合与枚举的简明概述

请添加图片描述
🔥引言

关于自定义类型除了我们常用的结构体,还有联合与枚举也是属于自定义类型。本篇将简单介绍联合与枚举基本概念和使用方法

请添加图片描述

Alt

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述

文章目录

  • 一、联合体(Union)
    • 1.1 联合体的声明
    • 1.2 联合体的特点
    • 1.3 结构体和联合体内存布局对比
    • 1.4 计算联合体的大小
    • 1.5 联合体的实际使用样例
  • 二、Enum(枚举)
    • 2.1 枚举类型的声明
    • 2.2 枚举类型的优点
    • 2.3 枚举类型的使用


一、联合体(Union)

1.1 联合体的声明

联合体是一个或多个成员组成,其中成员可以是不同类型,并且所有成员共用同一块内存空间,所以联合体也称为共用体。联合体声明的关键字是union。

//联合体类型的声明
union Un
{char c;int i;
};
int main()
{union Un un;//联合体的定义sizeof("%d\n,sizeof(un)");-->4return 0;
}

1.2 联合体的特点

联合体的特点:

  • 联合体所有成员共用同一块内存空间,一个联合体变量的大小,至少是最大成员的大小,编译器只为最大的成员分配足够大的空间
  • 给联合体其中一个成员赋值,其他成员的值也会变化
代码一
union Un
{char c;int i;
};
int main()
{union Un un = {0};// 下⾯输出的结果是⼀样的吗?printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}结果:001AF85C001AF85C001AF85C
代码二
union Un
{char c;int i;
};
int main()
{union Un un = {0};un.i = 0x11223344;un.c = 0x55;printf("%x\n", un.i);return 0;
}
结果:11223355

在这里插入图片描述

说明】:
从代码一输出的结果是相同的,说明联合体中成员变量是一块空间存储。从代码二输出中,第四个字节的内容被修改位55,对联合体中成员赋值,会影响联合体的全部成员,char类型只占用一个字节。

1.3 结构体和联合体内存布局对比

struct Su
{char c;int i;
}S;
Union Un
{char c;int i;
}un;

在这里插入图片描述

说明】:结构体是通过以为空间换取时间设计("浪费"空间),而联合体是节省空间


1.4 计算联合体的大小

规则如下】:

  • 联合体的大小至少是最大成员的大小
  • 当最大成员大小(联合体总大小)要对齐到最大对齐数的整数倍
#include <stdio.h>
union Un1
{char c[5]; 1 8 1//最大成员大小为5int i;  4 8 4
};//最大对齐数位4,最大成员大小为5,对齐到8是最大对齐数的整数倍union Un2
{short c[7]; 2 8 2//最大成员大小为7int i;  4 8 4
};//最大对齐数位4,最大成员大小为7,对齐到16是最大对齐数的整数倍int main()
{printf("%d\n", sizeof(union Un1));-->8printf("%d\n", sizeof(union Un2));-->16return 0;
}

1.5 联合体的实际使用样例

场景如下,搞一个礼品兑换,礼品兑换单中有三种商品:图书、被子、衬衫。每一种商品的信息:库存量、价格等相关的其他信息

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

如果单纯采用结构体,将变量全部写下来:

struct 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;//尺寸   
}

优点】:

  • 设计简单,使用方便

【缺点】:

  • 包含了各种的属性,内存占用比较大、浪费空间也加大了
  • 部分属性信息是常用的,有些商品不需这部分信息

解决办法:】把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体处理,再一定程度上节省了内存

配合上联合体设计:

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;
};

说明】:

将不同商品的本身属性使用联合体处理,初始化的时候是初始化一个联合体对象,联合体里面只支持初始化一个结构体成员,没法加中括号,再在中括号里面分别初始化,语法不允许

而且这种情况我们正常使用时本身就只会选择一个成员进行初始化。如果需要初始化多个对象,则将其放进一个结构体数组初始化,每个数组元素都是结构体单独初始化

联合体习题】:判断当前机器是大端还是小端(通过数字和地址关系)

int check_sys()
{union{int i;char c;}un.i=1;//00 00 00 01-->01 00 00 00(小端)return un.c 
}

二、Enum(枚举)

枚举顾名思义就是⼀>列举

列举可能的取值:用于定义一组具有离散值的常量,使数据更简洁、方便使用,关枚举的关键字enum。

2.1 枚举类型的声明

比如列举:星期一到星期日十有限的七天或者性别、颜色等。

enum Day
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};
enum Sex
{Man;Woman;
}

以上定义的enum Day、enum Sex都是枚举类型,而{}中枚举类型的可能取值称为枚举常量

在声明枚举类型的时候,可以同时对枚举常量初始化(枚举常量都是有值的,默认从0开始,并且依次递增)

enum Sex
{Man=10;Woman;//11
}

2.2 枚举类型的优点

问题】:

这里就像#define定义常量,为什么还有枚举这样子数据类型

枚举的优点】:

  1. 增加代码的可读性和可维护性
  2. 枚举类型有类型检查,更加严谨
  3. 便于调试,预处理阶段会删除#define定义的符号
  4. 一次可以定义多个枚举常量,使用方便
  5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

2.3 枚举类型的使用

enum Color
{Red=2;Blue=1;
}
enum Color clr=Blue;

使用枚举常量给枚举变量赋值,也可以拿整数给枚举变量赋值(C语言可以,C++不行,C++检查比较严格)

使用场景】:

比如:在枚举类型中定义事物的编号,通过输入数字(编号),找到对应的事情

enum color
{Red=1;Blue;//1递增为2
}
int main()
{	enum color favorite_color;printf("请输入你喜欢的颜色:(1.Red,2.Bule)");//输入1或2去代表Red或Bulescanf("%u",&favorite_color);switch(favorite_color){case Red(Red==1):printf("%你喜欢的颜色为红色");break;case Blue(Blue==2):printf("%你喜欢的颜色为蓝色");break;default :printf("没有喜欢的颜色")} 
}

【说明】:这里不是输入枚举对象,而是枚举对象对应的数字。


在这里插入图片描述
以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二C语言笔记,希望对你在学习C语言中有所帮助!

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

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

相关文章

BMC术语

BMC&#xff08;Baseboard Management Controller&#xff09;&#xff0c;用来进行远程带外管理的设备&#xff0c;BMC 是独立于服务器系统之外的小型操作系统&#xff0c;是一个集成在主板上的芯片&#xff0c;也有产品是通过 PCIE 等形式插在主板上&#xff0c;对外表现形式…

[C++][Warning] Default arguments on virtual or override methods are prohibited

1 引言 C作为一门强大的编程语言&#xff0c;广泛用于开发各种类型的应用程序&#xff0c;特别是在面向对象编程领域。在C中&#xff0c;虚函数和重写函数是面向对象编程的关键概念&#xff0c;它们允许我们建立强大的继承层次结构和多态行为。默认参数则为函数提供了额外的灵…

《NoSQL数据库技术与应用》MongoDB数据库操作

《NoSQL数据库技术与应用》 教学设计 课程名称&#xff1a;NoSQL数据库技术与应用 授课年级&#xff1a; 20xx年级 授课学期&#xff1a; 20xx学年第一学期 教师姓名&#xff1a; 某某老师 2020年5月6日 课题 名称 第3章 MongoDB数据库操作 计划学时 14课时 内容 分析 如果说…

如何在.NET中集成SignalR

SignalR 简介 SignalR是一个开放源代码库&#xff0c;可用于简化向应用添加实时Web功能&#xff0c;实时Web功能使服务器端代码能够将内容推送到客户端。 SignalR开源库&#xff1a;https://github.com/SignalR/SignalR SignalR 应用场景 需要高频次从服务器获取信息的应用&am…

QML_Switch控件_3选2的控制算法

QML_Switch控件_3选2的控制算法 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.5Window {visible: truewidth: 400height: 400title: qsTr("Hello World")property int num: 0Row {spacing: 10Switch {id: switch1onCheckedChanged: {…

Android基础-初识Android系统架构

Android系统架构详解 Android系统作为一款广泛应用于智能手机、平板电脑等设备的操作系统&#xff0c;其架构的设计对于系统的稳定性、可扩展性和用户体验至关重要。Android系统架构是一个复杂的层次结构&#xff0c;旨在实现硬件与软件之间的高效协同工作&#xff0c;为用户提…

redis如何查看参数值

在Redis中&#xff0c;查看参数值可以使用CONFIG GET命令。以下是查看Redis参数值的详细步骤和格式化的回答&#xff1a; 1. 启动Redis客户端 首先&#xff0c;你需要打开Redis的客户端。这通常可以通过在终端或命令提示符中输入redis-cli命令来实现。 2. 连接到Redis服务器…

找出缺失的观测数据

代码实现&#xff1a; 在缺失的 n 个观测数据中&#xff0c;有 y 个观测数据是 x1&#xff0c;其余观测数据都是x int* missingRolls(int *rolls, int rollsSize, int mean, int n, int *returnSize) {int m rollsSize;int sum mean * (n m);int missingSum sum;for (int i…

Java进阶:详解与实战Java Stream API

Java进阶&#xff1a;详解与实战Java Stream API &#x1f31f; Java进阶&#xff1a;详解与实战Java Stream API &#x1f31f;摘要引言一、Java Stream API介绍&#x1f4da;1. 什么是Java Stream API&#xff1f;2. Java Stream API支持的功能3. 使用Java Stream API的优势…

Python-3.12.0文档解读-内置函数id()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 概述 参数 返回值 特性 实现细节&#xff08;CPython&#xff09; 安全…

F12 网络请求类型:Fetch与XHR的区别

F12 网络请求类型&#xff1a;Fetch与XHR的区别 引言 在Web开发中&#xff0c;浏览器的F12开发者工具是调试网络请求的重要工具。通过F12&#xff0c;我们可以查看各种类型的网络请求&#xff0c;包括fetch和XMLHttpRequest&#xff08;XHR&#xff09;。这两种技术都用于在浏…

Linux——Linux服务管理

服务管理大作业要求&#xff1a; 基本拓扑如下&#xff1a; 按照要求完成基本的系统管理任务&#xff1a; 完成所有系统的主机名、网络配置&#xff1b; 本次作业共需要3台虚拟机&#xff0c;分别作为客户端、综合应用服务器、存储服务器。三台虚拟机操作系统均为CentOS-Stream…

5.2网安学习第五阶段第二周回顾(个人学习记录使用)

本周重点 ①HIDS的基本应用(suricata) ②Suricata的基本应用 ③Suricata的流量检测 ④Suricata的https流量检测 ⑤利用Elastic整合Suricata日志 ⑥利用Wazuh对Suricata主动响应 本周主要内容 ①HIDS的基本应用(suricata) 1、NIDS 1、定义&#xff1a;网络入侵检测系统…

算法简单笔记

本人大二下学期报了中国大学生计算机设计大赛、珠澳计算机设计大赛、区块链软件设计大赛、蓝桥杯......然后一直准备着设计大赛的比赛&#xff0c;根本没空管蓝桥杯&#xff0c;就省考前准备了一星期&#xff0c;感觉是没有希望了&#xff0c;但是很莫名其妙的就拿了蓝桥杯Java…

悲痛都会过去,唯有当下值得珍惜

在生活的长河中&#xff0c;我们都会经历各种各样的悲痛与挫折&#xff0c;无论是来自原生家庭的困扰&#xff0c;婚姻中的曲折&#xff0c;还是小时候的创伤、男女关系中的纠葛、校园时期的霸凌。然而&#xff0c;当我们回首过去&#xff0c;曾经以为无法逾越的痛苦&#xff0…

通过css实现------简单边框流动特效

效果展示 代码部分 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice…

C++学习/复习5--构造函数与初始化/static成员/友元/内部类/匿名对象/编译器的拷贝构造优化

一、本章概要 二、再谈构造函数 1.构造体赋初值与初始化 2.初始化列表与初始化 2.1定义 2.2注意事项与举例 3.explicit关键字与构造函数 3.1隐式类型转换 也叫做自动类型转换 这种转换通常是从存储范围小的类型到存储范围大的类型&#xff0c;或者是从低精度的数值类型到高…

简述vue-loader是什么?使用它的用途有哪些

vue-loader是一个webpack的加载器(loader)&#xff0c;主要用于将Vue组件的单文件(.vue文件)转换为JavaScript模块。使用vue-loader的主要用途包括&#xff1a; 解析.vue文件&#xff1a;vue-loader能够解析.vue文件中的模板、样式和脚本&#xff0c;并将它们分离出来进行处理…

python爬虫学习(1)——初识爬虫

520那天我向心仪的女孩要微信&#xff1a;“女神&#xff0c;能给我你的微信号吗&#xff1f;” 女神&#xff1a;“爬&#xff01;&#xff01;&#xff01;&#xff01;” 从那天开始&#xff0c;我就决定要学好爬虫&#xff0c;爬到女神微信号&#xff01;&#xff01;&…

引入安全生产培训云平台,实现“人人讲安全、个个会应急”

引入安全生产培训云平台&#xff0c;旨在全面提升企业及员工的安全意识与应急处理能力&#xff0c;通过数字化手段实现“人人讲安全、个个会应急”的目标。这一平台的构建和应用&#xff0c;不仅促进了安全知识的普及&#xff0c;还极大提高了培训的效率与效果。以下是该平台几…