自定义类型联合体

目录

  • 联合体
    • 联合体类型的声明
    • 联合体的特点
    • 相同成员的结构体和联合体对比
    • 联合体大小的计算
    • 联合体的应用
    • 联合的一个练习

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐓🏀 python

联合体

联合体类型的声明

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。

但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。

所以联合体也叫:共用体

给联合体其中一个成员赋值,其他成员的值也跟着变化

联合体的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)

我们来看一个代码

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

我们知道char类型是占一个字节,int类型是占4个字节的,按理说联合体的大小应该至少是大于或等于5个字节才对,但是运行结果却恰恰相反
在这里插入图片描述
我们再回头看上面的一句话
在这里插入图片描述
编译器只为最大的联合体成员分配足够的内存空间,那么这里的最大的成员就应该是int类型

所以联合体的内存大小就是int类型的大小,而char类型就是和int类型共用那4个字节的内存

为了更深入的了解联合体和联合体成员的内存是怎样分配的,我们来看下一段代码

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

在这里插入图片描述
我们发现结果是一模一样的,我们可以推测当int i的第一个字节是属于char c的,所以我们取地址c就是取地址i的第一个字节

在这里插入图片描述
而联合体又叫共用体,说明我们只要改变其中任意一个成员,那其他成员也是会受到影响的

联合体也是可以匿名的

union 
{
	char c;
	int i;
}u;

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

我们再对比一下相同成员的结构体和联合体的内存布局情况

//结构体
struct S
{
	char c;
	int i;
};
struct S s = { 0 };
//联合体
union Un
{
	char c;
	int i;
};
union Un un = { 0 };

联合体大小的计算

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

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

下面会涉及到内存对齐
可以先看一下我之前写的一篇文章自定义类型结构体(中)

#include <stdio.h>
union Un1
{
	char c[5];//大小5
	int i;//大小4
};
union Un2
{
	short c[7];
	int i;
};
int main()
{
	//下⾯输出的结果是什么?
	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
}

在这里插入图片描述
对于un1,char c[5]其实相当于放了5个char类型的变量,每个变量只占一个字节,而int i是占的4个字节,因此最大对齐数的整数倍数应该是4,最后还得浪费3个字节变成8个字节才行

而un2, short c[7]中是相当于放了7个short类型的变量,每个变量是2个字节,而int i是4个字节,所以最大对齐数是4,因此最后需要浪费两个字节将14变成16才可以

使用联合体是可以节省空间的,举例:
比如,我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。
每一种商品都有:库存量、价格、商品类型和商品类型相关的其他信息

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

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

商品是图书,就不需要design、colors、sizes。

当我们需要用到书的信息时,我们只需要用item.book就可以查询,其他的也是类似的

所以我们就可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体起来,这样就可以介绍所需的内存空间,一定程度上节省了内存

联合的一个练习

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

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("大端\n");
}

在这里插入图片描述

因为char c和int i是共用内存的,而且char c是占的第一个字节,所以我们只需要看c最后的值是多少就可以判断编译器是大端存储还是小端存储

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《向量数据库指南》——用了解向量数据库Milvus Cloud搭建高效推荐系统

了解向量数据库 ANN 搜索是关系型数据库无法提供的功能。关系型数据库只能用于处理具有预定义结构、可直接比较值的表格型数据。因此,关系数据库索引也是基于这一点来比较数据。但是 Embedding 向量无法通过这种方式直接相互比较。因为我们不知道向量中的每个值代表什么意思,…

Transformer:开源机器学习项目,上千种预训练模型 | 开源日报 No.66

huggingface/transformers Stars: 113.5k License: Apache-2.0 这个项目是一个名为 Transformers 的开源机器学习项目&#xff0c;它提供了数千种预训练模型&#xff0c;用于在文本、视觉和音频等不同领域执行任务。该项目主要功能包括&#xff1a; 文本处理&#xff1a;支持…

(附源码)基于SSM 车险事故自助理赔小程序-计算机毕设 84607

车险事故自助理赔小程序 摘要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;车险事故自助理赔小程序被用户普遍…

C++二分查找算法的应用:最小好进制

本文涉及的基础知识点 二分查找 题目 以字符串的形式给出 n , 以字符串的形式返回 n 的最小 好进制 。 如果 n 的 k(k>2) 进制数的所有数位全为1&#xff0c;则称 k(k>2) 是 n 的一个 好进制 。 示例 1&#xff1a; 输入&#xff1a;n “13” 输出&#xff1a;“3” …

Linux 实现文件后半部分的复制

继上次实现文件从后往前数2k的数据进行复制&#xff0c;此次要求是文件的一半且是后半部分。 即复制源文件sour_file的后半部分到dest_file 除了数据上从后2K变化到后一半之外&#xff0c;其他的几乎没有什么变化。 这道题的关键点就在于后一半怎么求&#xff0c;在经历了用 …

玩转AIGC:如何选择最佳的Prompt提示词?

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

LangChain+LLM实战---如何训练大模型(LLM)

英文原文&#xff1a;How to train your own Large Language Models 概要介绍 大型语言模型&#xff0c;如OpenAI的GPT-4或Google的PaLM&#xff0c;已经席卷了人工智能领域。然而&#xff0c;大多数公司目前没有能力训练这些模型&#xff0c;并且完全依赖于只有少数几家大型…

0基础学习PyFlink——时间滑动窗口(Sliding Time Windows)

在《0基础学习PyFlink——时间滚动窗口(Tumbling Time Windows)》我们介绍了不会有重复数据的时间滚动窗口。本节我们将介绍存在重复计算数据的时间滑动窗口。 关于滑动窗口&#xff0c;可以先看下《0基础学习PyFlink——个数滑动窗口&#xff08;Sliding Count Windows&#x…

【Midjourney入门教程2】Midjourney的基础操作和设置

文章目录 Midjourney的常用命令和基础设置1、 /imagine2、 /blend3、 /info4、 /subscribe5、 /settings&#xff08;Midjourney的基础设置&#xff09;6、 /shorten 有部分同学说我不想要英文界面的&#xff0c;不要慌&#xff1a; 点击左下角个人信息的设置按钮&#xff0c;找…

CoT: 思路链提示促进大语言模型的多步推理

CoT 总览摘要1 引言2 Chain-of-Thought Prompting3 算术推理 &#xff08;Arithmetic Reasoning&#xff09;3.1 实验设置3.2 结果3.3 消融实验3.4 CoT的鲁棒性 4 常识推理 &#xff08;Commonsense Reasoning&#xff09;5 符号推理 &#xff08;Symbolic Reasoning&#xff0…

SystemC入门之测试平台编写完整示例:全加器

导读: 本文将完整演示基于systemC编写一个全加器的测试平台。具体内容包括&#xff1a;激励平台&#xff0c;监控平台&#xff0c;待测单元的编写&#xff0c;波形文件读取。 1&#xff0c;main函数模块 搭建一个测试平台主要由&#xff1a;Driver, Monitor, DUT(design under …

Nginx编译安装和配置

官网:http://nginx.org/ 这里以1.20.2为例 Nginx是C语言写的 如果Linux系统上没有安装C编译环境 先执行下面命令 yum install -y gcc automake autoconf libtool make 如果不确定 可以使用命令查看 命令格式 rpm -q xxx 例如 说明有C编译环境 安装前需要安装4个依赖包…

基因组WGD的鉴定与分化时间

1. WGD 简介 全基因组复制(Whole genome duplications, WGD)是生物进化的重要因素之一&#xff08;导致基因组扩增的因素包括全基因组复制和转座子TEs&#xff09;, 所以WGD分析也是基因组分析经常用到的一种分析方法。 古 WGD 检测有两种方法&#xff0c;一种是共线性分析&a…

Spring Boot创建多模块项目

创建一个普通的Spring Boot项目, 然后只留下 pom.xml 剩下的都删掉 删除多余标签 标识当前为父模块 创建子模块 删除子模块中多余标签 声明父模块 在父模块中声明子模块

体验SOLIDWORKS旋转反侧切除增强 硕迪科技

大家在设计中经常使用的旋转切除命令在solidworks2024版本中迎来了新的增强&#xff0c;添加了旋转反侧切除选项。在设计过程中不必修改复杂的草图即可切除掉我们不需要的部分。使设计工作更加方便快捷。 打开零部件后&#xff0c;点击键盘上的S键并输入旋转切除以搜索该命令&a…

[极客大挑战 2019]Knife 1(两种解法)

题目环境&#xff1a; 这道题主要考察中国菜刀和中国蚁剑的使用方法 以及对PHP一句话木马的理解 咱们先了解一下PHP一句话木马&#xff0c;好吗&#xff1f; **eval($_POST["Syc"]);** **eval是PHP代码执行函数&#xff0c;**把字符串按照 PHP 代码来执行。 $_POST P…

使用HttpClient库的爬虫程序

使用HttpClient库的爬虫程序&#xff0c;该爬虫使用C#来抓取内容。 using System; using System.Net.Http; using System.Threading.Tasks; ​ namespace CrawlerProgram {class Program{static void Main(string[] args){// 创建HttpClient对象using (HttpClient client new…

【蓝桥杯基础题】门牌制作

👑专栏内容:蓝桥杯刷题⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停目录 一、题目描述二、题目分析三、代码汇总1、C++代码2、Java 代码四、总结1、枚举思想2、取余判断每位数字一、题目描述 题目链接:门牌制作 小蓝要为一条街的住户制作门牌号。这条街一共…

Powercli批量修改分布式交换机端口组

背景 需求&#xff1a; 批量修改虚拟机的分布式端口组 解决方式一&#xff1a; 三条命令解决&#xff1a;先获取目标虚拟机、获取目标端口组、修改虚拟机端口组、检查虚拟机状态。 $vm Get-VM -Name <虚拟机名称> $portGroup Get-VirtualPortGroup -Name <端口…

视频编码转换技巧:视频批量转码H264转H265,高效且顺畅

随着数字媒体的广泛应用&#xff0c;视频编码转换已成为一种普遍的需求。不同的视频格式和编码标准使得在不同设备上播放视频成为可能&#xff0c;同时也带来了兼容性和传输效率的问题。本文讲解引用云炫AI智剪使视频编码转换技巧&#xff0c;即批量将H264编码转换为H265编码&a…