自定义类型:【联合体和枚举】

一.联合体

1.联合体类型的声明

联合体像结构体一样,也是有一个或者多个成员组成,当然也可以不同的类型。但不同的是,比编译器只为最大的成员分配足够的内存空间,所有成员共用同一块内存空间。所以联合体也叫做:共用体。

联合体与结构体最不同的是,给联合体里的一个成员赋值,其他的成员也会随之变化。

联合体的声明其实也跟结构体大体一样

union Un
{char c;int i;
};
#include <stdio.h>
int main()
{union Un u = { 0 };printf("%zd", sizeof(u));return 0;
}

其实就是把struct给换成了union。

2.联合体的特点

上面的代码打印出来最终是4。可为什么是4呢?我们来探讨一下

首先,我们先思考一下,我上面说了一个东西就是所有成员共用一块空间。那么我在这个联合体里c和i的地址一样吗?我们来打印测试一下这两个地址是否一样。

其实是一样的。那么我们是不是可以得出一个结论:我们创建的一个成员变量i占了4个字节,这个c占了一个字节,其实i的第一个字节同样也是c的那一个字节。

再来看这个代码

union Un
{char c;int i;
};
#include <stdio.h>
int main()
{union Un u = { 0 };u.i = 0x11223344;u.c = 0x55;return 0;
}

再来看在内存中的存储,我改变了u.c的值,同样这里的44变成了55.

3.联合体大小的计算

想要计算联合体的大小,需要先明白两点

1.联合的大小至少是最大成员的大小

2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

注意了,联合体的大小是至少是最大成员的大小,可不一定是最大成员的大小,举个例子:

#include<stdio.h>
union Un
{             //类型大小  默认对齐数  对齐数char c[5];//1         8        1int i;    //4         8        4
};
int main()
{union Un u = { 0 };printf("%d", sizeof(u));return 0;
}

打印出来的是8

因为c有5个char类型的元素。直接就占用了5个字节,根据上面的第二点,我们需要对齐到4的倍数,所以就是8.

4.联合体的使用

根据我前面所说的,使用联合体我们是可以节省空间的。

那么假如我们举行了一个游戏,参与游戏的人,获得了礼品兑换的机会。有三种商品我们可以兑换:图书,杯子和衬衫。而每一种商品都有:库存量,价格等其他信息。

还有一些商品的特有属性

图书:书名,作者,页数

杯子:设计

衬衫:设计,颜色,尺寸

如果我想用代码把这些结构写出来,如果不认真思考的话,可能就直接把这些一窝蜂的都写到结构体里去了。

可能写出来是这样的

struct gift_list
{//公共属性int stock_number;//库存量double price;//定价int item_type;//商品类型//特殊属性char title[20];//书名char author[20];//作者int num_pages;//页数char design[30];//设计int color;//颜色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 color;//颜色int sizes;//尺寸}shirt;}item;
};

在这里有一个联合体里面包含了三个结构体成员,我们把每一件物品的特属性都分别放在了book,mug和shirt里面,前提是当我们在使用其中一个的时候是不会影响其他的两个,这时我们就可以使用联合体的方式来很大程度的节省空间。

5.联合体的小练习

写一个程序来判断当前机器是大端还是小段

#include <stdio.h>
int check_sys()
{union Un{char c;int i;}u;u.i  = 1;return u.c;
}
int main()
{int ret = check_sys();if (ret = 1){printf("是小端\n");}else{printf("是大端");}return 0;
}

可以复制来看一下打印出来的多少。

二.枚举类型

1.枚举类型的声明

所谓枚举,其实就是一一列举的意思。它的关键字是enum。比如三原色:

enum Color
{RED,GREEN,BLUE,
};

这就是把他们一一列举出来,{}里的内容也就是枚举类型的可能取值,也叫做枚举常量。枚举类型也是可以创建变量的,比如:

int main()
{enum Color color=RED;return 0;
}

值得注意的是,枚举内部的成员其实也有数值,我们可以单独打印出来它们的值来看一下。

#include<stdio.h>
enum Color
{RED,GREEN,BLUE,
};
int main()
{enum Color color=RED;printf("%d\n", RED);printf("%d\n", GREEN);printf("%d\n", BLUE);return 0; 
}

最终打印出来的值按顺序分别是0,1,2

我们在主函数里是不能改变这三个值的,因为它们也是常量。但是,我们可以在枚举体的内部改变它们的值:

我们把第二个值改了之后,这里的第二个值和第三个值也随之变化了。

2.枚举类型的优点

1.增加代码的可读性和可维护性

2.和#define定义的标识符相比枚举有类型检查,更加严谨(#define定义的标识符是没有类型可言的,但是枚举是有类型的,比如我给一个enum Color =RED;在c++中就不能写成enum Color =0,其实RED就是0)

3.便于调试,预处理阶段会删除#define定义的符号(在预处理的时候,如果代码里有#define定义的标识符,会直接给替换掉)

4.使用方便,一次可以定义多个常量

5.枚举常量是遵循作用域规则的,枚举声明在函数里,只能在函数里使用

感谢大家的观看,如果有错误,还请大家多多指正。

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

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

相关文章

GEE22:基于目视解译的土地利用分类(随机森林监督分类)

采样点信息&#xff1a; 设置一下采样点参数&#xff1a; 代码&#xff1a; //设置研究区位置 var table ee.FeatureCollection("users/cduthes1991/boundry/China_province_2019"); var roi table.filter(ee.Filter.eq(provinces,beijing)); Map.centerObjec…

公司服务器被.rmallox攻击了如何挽救数据?

公司服务器被.rmallox攻击了如何挽救数据&#xff1f; .rmallox这种病毒与之前的勒索病毒变种有何不同&#xff1f;它有哪些新的特点或功能&#xff1f; .rmallox勒索病毒与之前的勒索病毒变种相比&#xff0c;具有一些新的特点和功能。这种病毒主要利用加密技术来威胁用户&am…

一、图片隐写[Stegsolve、binwalk、010editor、WaterMark、BlindWaterMark、文件头尾]

工具配置 1.Stegsolve 工具地址&#xff1a;http://www.caesum.com/handbook/Stegsolve.jar 解释&#xff1a;该工具需要安装jar包后才能配合使用&#xff0c;下面同时会给出快速打开工具的代码&#xff0c;需要两个文件&#xff0c;启动的时候启动vbs文件 start.bat java …

基于SpringBoot的“财务管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“财务管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 系统登录界面图 管理员功能界面图…

解决GNU Radio+USRP实现OFDM收发在接收端QPSK星座图映射无“抖动”问题

文章目录 前言一、遇到的问题二、解决方案三、重新编译安装四、验证五、资源自取 前言 本文记录在 GNU RadioUSRP 实现 OFDM 收发时&#xff0c;在接收端 QPSK 星座图映射无“抖动”问题的解决方法&#xff0c; 一、遇到的问题 我遇到的问题是&#xff0c;现在搭建的 OFDM 模…

定义类强化——定义Goods类表示商品

现需要编写一个计算商品总价值的程序&#xff0c;现要求&#xff1a; 1、定义一个表示商品的类&#xff1a;Goods&#xff0c;Goods类要包含&#xff1a; 一个私有成员变量String name表示商品的名称&#xff1b;一个私有成员变量float price表示商品的价格&#xff0c;并定义…

微服务(基础篇-007-RabbitMQ部署指南)

目录 05-RabbitMQ快速入门--介绍和安装_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p65&vd_source60a35a11f813c6dff0b76089e5e138cc 1.单机部署 1.1.下载镜像 1.2.安装MQ 2.集群部署 2.1.集群分类 2.2.设置网络 视频地址&#xff1a; 05-Rab…

解析商业电子邮件泄露:深度剖析攻击的含义

本文的第1部分清楚地介绍了什么是商业电子邮件泄露&#xff08;BEC&#xff09;&#xff0c;检测它的方法&#xff0c;以及如何防御。商业电子邮件泄露第2部分&#xff1a;攻击的含义将讨论BEC事件是如何发生的&#xff1f;如果你不够小心&#xff0c;BEC会在很多方面对你的业务…

【力扣hot100】两数之和、字母异位词分组

【1】两数之和 public class TwoNumAddiction {public static void main(String[] args) {int[] nums {3,3};int target 6;int[] indexArr new SolutionNumAddiction().twoSum(nums, target);for (int index : indexArr) {System.out.println(index);}} }class SolutionNumA…

最优算法100例之13-输出第n个丑数

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当…

国内好用的chatGPT和AI绘图工具

分享一个比较好用的AI 分享一个比较好用的AI&#xff0c;只是需要开通会员&#xff0c;目前官网的价格是&#xff1a;298&#xff0c;开通之后可以使用chatgpt4、AI绘画、图片融合等等&#xff01;不开通的话是可以免费使用15次的&#xff0c;下面是一些介绍图片&#xff01;链…

2013年认证杯SPSSPRO杯数学建模B题(第一阶段)流行音乐发展简史全过程文档及程序

2013年认证杯SPSSPRO杯数学建模 B题 流行音乐发展简史 原题再现&#xff1a; 随着互联网的发展&#xff0c;流行音乐的主要传播媒介从传统的电台和唱片逐渐过渡到网络下载和网络电台等。网络电台需要根据收听者的已知喜好&#xff0c;自动推荐并播放其它音乐。由于每个人喜好…