【自定义类型详解】完结篇——联合体(共用体)与枚举详解

先赞后看已成习惯!!!

联合体

1. 联合体的定义

联合体又叫共用体,它是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。给联合体其中⼀个成员赋值,其他成员的值也会跟着变化。

联合体的结构类似于结构体,由关键词union和多个成员变量构成:

union (union  tag)
{
member definition;
member definition;

member definition;
} [more  union variables];

union tag为用户自己编译;member definition为成员变量:可以为 int char等等;

[more  union variables]为你设置的联合体名称

2.联合体类型的声明

我们来看一下这个代码:

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

输出值为: 4

 为什么是4呢?

 在我们设定的联合体中,存在char(1字节)、int(4字节)类型,在联合体的定义中,联合体的成员会共同占用一块内存空间,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)

 (1)联合体

union Un
{int n;char un;};

(2)联合体嵌套

union Un1
{int n;char un;}; 
union Un2
{int n;char un;union Un1;
};

(3)匿名联合体

union 
{int n;char un;}; 

 (4)自定义联合体

typedef union un
{int n;char un;}un1; 

让我们在来看下面两段代码

代码1:

#include <stdio.h>
//联合类型的声明
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;
}

000000EA08B3FAE4
000000EA08B3FAE4
000000EA08B3FAE4

我们会发现他们都指向同一个地址;

代码2:

#include <stdio.h>
//联合类型的声明
union Un
{char c;int i;
};
int main()
{//联合变量的定义union Un un = { 0 };un.i = 0x11223344;un.c = 0x11;//这里是16进制printf("%x\n", un.i);return 0;
}

这里的操作方法与结构体类似,可以利用(.)和(->)操作符

我们再来看看代码2中的输出:

输出:  11 22 33 11

有什么不同的吗 ?   

我们发现在最后位置的44受un.c的赋值的影响变为了11;

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

struct S                               union un
{                                      {char c;                                 char c;             int i;                                  int i;
};                                     };
struct S s = {0};                      union Un un = {0};

                                               结构体与联合体在内存中的区别

4.联合体的大小计算

  • 至少是最大成员的大小
  • 当最大成员大小不是最大对齐数的整数倍,就要对齐到最大对齐数的整数倍

使用联合体是可以节省空间的,对于具有公共属性的成员时我们就可以利用联合体节省空间:

例如:当我们购买商品时

公共属性:

//商品名

//价格

//类型

......

私有属性:

//书名

//出版商

//作者

......

5.利用联合体判断大小端

回顾:

#include<stdio.h>int check_sys()
{int i = 1;return (*(char*)&i);//先取出i的地址,再将i的(int*)转化为char*,最后在解引用,取出低地址的一个字节;
}int main()
{int ret = check_sys();//返回1,则说明低字节放在低地址//返回0,则说明高字节放在低地址if (ret = 0) {printf("大端存储");}else {printf("小端存储");}return 0;
}

 在前面中我们是利用char*和int*读取的字节大小的不同所判断;在这里我们也可以利用相同的原理使用联合体来判断

int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c; //返回1是⼩端,返回0是⼤端
}
int main()
{int ret = check_sys();if (ret == 1){printf("⼩端\n");}else{printf("⼤端\n");}return 0;
}

枚举

1.枚举的声明

枚举意为-->列举

(1) 普通枚举
接下来我们举个例子,比如:我们要定义一个星期 , 使用#define 来为每个整数定义一个别名:

#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7

我们会发现这个的代码量就比较多,接下来我们看看使用枚举的方式:

enum DAY
{
      MON=1, //指定从1开始,否则默认从0开始
      TUE,
      WED,
      THU, 
      FRI, 
      SAT, 
      SUN
};

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

(2) 匿名枚举
和匿名结构体与匿名联合体类似,枚举也有匿名类型。

enum
{APPLE,BANANA,ORANGE
};

(3) typedef枚举
我们也可以使用typedef简化枚举。

typedef enum DAY
{MON = 1, //指定从1开始,否则默认从0开始TUE,WED,THU,FRI,SAT,SUN
}DAY;

7.2 打印枚举常量

typedef enum DAY
{MON, TUE,WED,THU,FRI,SAT,SUN
}DAY;
int main()
{for (int i = MON; i < SUN; i++){printf("%d ", i);}return 0;
}

2.枚举的优点

我们可以使用#define 定义常量,为什么非要使用枚举?
枚举的优点:
  • 增加代码的可读性和可维护性和#define定义的标识符比较枚举有类型检查,更加严谨。
  • 便于调试,预处理阶段会删除 #define 定义的符号
  • 使用方便,⼀次可以定义多个常量
  • 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使用 

3.枚举的应用

#include <stdio.h>int main()
{enum color {red = 1, green, blue 
//red = 1 是为了防止输入1时,输出为green};//枚举了enum  color favorite_color;//用户输入数字来选择颜色 printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): \n");scanf("%d", &favorite_color);switch (favorite_color){case red:printf("你喜欢的颜色是red\n");break;case green:printf("你喜欢的颜色是green\n");break;case blue:printf("你喜欢的颜色是blue\n");break;default:printf("你没有选择你喜欢的color\n");}return 0;
}#include <stdio.h>int main()
{enum color {red = 1, green, blue 
//red = 1 是为了防止输入1时,输出为green};//枚举了enum  color favorite_color;//用户输入数字来选择颜色 printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): \n");scanf("%d", &favorite_color);switch (favorite_color){case red:printf("你喜欢的颜色是red\n");break;case green:printf("你喜欢的颜色是green\n");break;case blue:printf("你喜欢的颜色是blue\n");break;default:printf("你没有选择你喜欢的color\n");}return 0;
}

oi!!!点个赞走吧!!!

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

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

相关文章

kaggle 房价预测 得分0.53492

流程 导入需要的包引入文件,查看内容数据处理调用模型准备训练输出结果 导入需要的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.model_selection import train_test_split from sklearn.linear_model i…

适合各大资源网投稿html源码

源码介绍 适合各大资源网投稿html源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果预览 源码下载 适合各大资源…

数据分析(1)

数据分析基础&#xff08;1&#xff09; 为了让刚开始学习的朋友对数据分析有一个清晰的整体认识&#xff0c;因此笔者在此对数分进行一个较为详细的介绍有助于大家更好的在宏观层面进行理解&#xff0c;避免在后续学习中产生迷茫。 数据分析的概念 定义&#xff1a;数据分析…

Oracle体系结构初探:聊聊REDO

上一篇文章写了undo&#xff08;文章链接&#xff1a;聊聊UNDO&#xff09;&#xff0c;这篇和大家一起聊聊redo。redo如果按照我的傻瓜翻译&#xff0c;意为再次去做、重新去做。Oracle官方对于redo的描述是&#xff1a;记录对数据所做的所有更改&#xff0c;包括未提交和已提…

Vue3——组件基础

组件基础 1. 组件定义与使用 1.1 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>组件基础&l…

Docker - 镜像、容器、仓库

原文地址&#xff0c;使用效果更佳&#xff01; Docker - 镜像、容器、仓库 | CoderMast编程桅杆Docker - 镜像、容器、仓库 提示 这个章节涉及到 Docker 最核心的知识&#xff0c;也是在使用过程中最常使用到的&#xff0c;需要重点学习。 什么是Docker镜像、容器、仓库&…

leetcode:438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s "cbaebabacd", p "…

前端工程化01-复习jQuery当中的AJAX

4.1、基础概念 什么是服务器 一台存储网站内容、网站文件的电脑 什么是资源 网站中使用的文件&#xff08;html、css、图片、…&#xff09;这些东西就叫做资源数据也是服务器上的资源&#xff0c;而且是一个网站的灵魂 客户端 客户端应该指上网的设备但是在前端开发中&a…

Web后端-请求响应

黑马程序员JavaWeb开发教程 文章目录 一、请求1、简单参数2、实体参数3、数组集合参数&#xff08;1&#xff09;数组参数&#xff08;2&#xff09;集合参数 4、日期参数5、json参数&#xff08;1&#xff09;在Postman中怎么发起请求来传递JSON格式的请求参数&#xff08;2&a…

精通MongoDB聚合操作API:深入探索高级技巧与实践

MongoDB 聚合操作API提供了强大的数据处理能力&#xff0c;能够对数据进行筛选、变换、分组、统计等复杂操作。本文介绍了MongoDB的基本用法和高级用法&#xff0c;高级用法涵盖了setWindowFields、merge、facet、expr、accumulator窗口函数、结果合并、多面聚合、查询表达式在…

卷王问卷考试系统/SurveyKing调查系统源码

SurveyKing是一个功能强大的开源调查问卷和考试系统&#xff0c;它能够快速部署并适用于各个行业。 这个系统提供了在线表单设计、数据收集、统计和分析等功能&#xff0c;支持20多种题型&#xff0c;提供多种创建问卷的方式和设置。 项 目 地 址 &#xff1a; runruncode.c…

C++相关概念和易错语法(7)(初始化列表、隐式类型转换、友元)

1.初始化列表 初始化列表是集成在构造函数里面的&#xff0c;对象在创建的时候一定会调用构造函数&#xff08;就算不显式定义&#xff0c;也会自动生成并调用&#xff09;。初始化列表就是这些对象的成员变量在创建的时候初始化的地方。 下面是使用的例子&#xff0c;可以先…

香港服务器_免备案服务器有哪些正规的?企业、建站方向

香港服务器&#xff0c;是最受欢迎的外贸、企业建站服务器&#xff0c;在个人建站领域&#xff0c;香港服务器、香港虚拟主机都是首选的网站服务器托管方案&#xff0c;不仅其具备免备案的特点&#xff0c;而且国内外地区访问速度都很快。那么&#xff0c;现今2024年个人和企业…

项目如何部署

我们平常写的项目通常只能在本机上运行&#xff0c;要想项目能被远程访问就不得不谈到项目部署的知识&#xff0c;接下来我通过实际操作的操作让大家来上线一个vuespringBoot项目。 1.在windows上将vue部署到nginx服务器上 介绍nginx Nginx是一款高性能的Web服务器和反向代理服…

C#语法知识之循环语句

5、循环语句 文章目录 1、while思考1 斐波那契数列思考2 判断一个数是否为质数思考3 找出100以内的质数 2、do...while3、for思考1 找水仙花数思考2 乘法表 1、while 1、作用 让代码重复去执行 2、语法相关 while(bool类型值){//当满足条件时&#xff0c;就会执行while语句…

【GIS教程】ArcGIS做日照分析(附练习数据下载)

我国对住宅日照标准的规定是:冬至日住宅底层日照不少于1小时或大寒日住宅层日照不少于2小时(通常以当地冬至日正午12时的太阳高度角作为依据)。因冬至日太阳高度角最低&#xff0c;照射范围最小&#xff0c;如果冬至日12&#xff1a;00建筑物底层能够接收到阳光&#xff0c;那么…

Python数据可视化库—Bokeh与Altair指南

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在数据科学和数据分析领域&#xff0c;数据可视化是一种强大的工具&#xff0c;可以帮助我们…

Docker - HelloWorld

原文地址&#xff0c;使用效果更佳&#xff01; Docker - HelloWorld | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-helloworld.html 开始之前 在学习本小节之前&#xff0c;你必须确保你正确安装了 Docker&#xff0c;正确安装 Docker 是后续学习的…

墨子web3实时周报

蚂蚁集团Web3研发进展与布局 国内Web3赛道的领军企业——蚂蚁集团&#xff0c;凭借其在前沿科技领域的深耕不辍&#xff0c;已在Web3技术研发疆域缔造了卓越战绩。特别是在引领行业革新的关键时刻&#xff0c;集团于今年四月末震撼推出了颠覆性的Web3全套解决方案&#xff0c;…

java通过maven导入本地jar包的三种方式

一、引入lib下加载&#xff08;加载过后打包&#xff0c;以后再次使用不用再次导入&#xff09; 首先创建一个用于创建jar包的项目&#xff0c;并测试能否成功运行 讲项目打包 在需要引入的项目中创建lib目录 并把刚才打包的jar复制进去 通过dependency引入jar包 groupId、art…