【C语言】联合体与结构体如何巧妙配合使用节省内存空间?

news2025/7/18 11:57:08

本篇文章目录

  • 1. 联合体的特点
  • 2. 计算联合体占用内存大小
  • 3. 利用联合体的特点判断当前机器是以什么字节序顺序存储数据?
  • 4. 联合体什么时候使用?

1. 联合体的特点

联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

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

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


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

在这里插入图片描述

  1. 因为是共用一块内存空间,所以对于起始地址而言三者都是一样的。
  2. 0x11223344实际上在内存中是以小端字节序存储:44 33 22 11,联合体的内存空间对每个成员而言是共用的,只是每个成员能访问的大小根据自身的数据类型决定,i能使用4个字节,c则能使用1个字节,结果为11223355的原因想必不难理解。

2. 计算联合体占用内存大小

  1. 联合的大小至少是最大成员的大小
  2. 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include <stdio.h>
union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};
int main() {
	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
}

在这里插入图片描述
Un1的最大对齐数不是5!char数组实际上只是算作5个char类型变量。i的大小作为对齐数,但却不是最大成员,char数组才是最大成员,4个字节存不下char数组(5个字节),所以要对齐到4的倍数8才能存下。Un2相同道理。

3. 利用联合体的特点判断当前机器是以什么字节序顺序存储数据?

#include <stdio.h>
union Un1
{
	char c;
	int i;
};
int main() {
	union Un1 un;
	un.i = 1; 
	if (un.c == 1) {
		printf("小端字节序");
	} 
	else {
		printf("大端字节序");
	}
	return 0;
}

在这里插入图片描述

1在内存中如果是以小端字节序存储的,那么是这个样子:00000001 00000000 00000000 00000000(十六进制:01 00 00 00)。c是char类型,只能访问1个字节大小的数据,如果访问到的值是1,说明当前机器就是小端字节序存储数据。

4. 联合体什么时候使用?

某些成员不会同一时间使用,这时使用联合体是可以节省空间的。

比如某个商店有一个活动要上线一个礼品兑换单,兑换单中有三种商品:图书、杯子、衬衫。

这三个商品都有互相相同的信息:库存量、价格和商品类型。

不同的信息则有:

  1. 图书:书名、作者和页数。
  2. 杯子:设计。
  3. 衬衫:设计、可选的颜色和尺寸。

如果我们不思考太多直接使用下面设计的结构体:

struct gift_list {
	// 公共属性
	int stock_number;
	double price;
	int item_type;
	// 图书
	char book_name[20];
	char author[30];
	int page_nums;
	// 杯子和衬衫共有
	char design[30];
	// 衬衫
	int colors;
	int sizes;
};

这样做实际上会浪费许多内存,比如对于图书而言,设计、颜色和尺寸并不会去用或者说并不重要,对于杯子和衬衫而言,书名、作者和页数更不可能用到。

如果只把公共属性摘出来放在结构体中,因为这是必须要有的。然后再把各个商品本身的属性放在联合体内,这样在一定程度上节省了内存开销。

struct gift_list {
	// 商品的公共属性
	int stock_number;
	double price;
	int item_type;

	union {
		struct {
			char book_name[20];
			char author[30];
			int page_nums;
		} book; // 图书

		struct {
			char design[30];
		} mug; // 杯子

		struct {
			char design[30];
			int colors;
			int sizes;
		} shirt; // 衬衫
	} item; // 商品
};

在联合体内,最大空间的毫无疑问是图书,存放图书数据的大小存放其它两种商品肯定是没问题的,在同一时间里不会浪费太多内存空间。

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

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

相关文章

微软最热门的10款前端开源项目!

本文来盘点微软开源的十大前端项目&#xff0c;这些项目在 Github 上获得了超过 45 万 Star&#xff01; Visual Studio Code Visual Studio Code 是一款由微软开发的开源的代码编辑器。它支持多种编程语言&#xff0c;如C、C、C#、Python、JavaScript 和 TypeScript 等&…

Nginx 代理 MySQL 连接

文章目录 Nginx 代理 MySQL 连接1. 前言2. 部署 Nginx&#xff0c;MySQL3. ngx_stream_core_module 配置方式3.1 stream3.2 server3.3 listen3.4 配置示例 4. 限制访问 IP4.1 allow4.2 deny4.3 配置示例 5. 综合案例 Nginx 代理 MySQL 连接 原文地址&#xff1a;https://mp.wei…

Windows批处理文件 @echo off作用

bat批处理文件代码中有echo off 这样的语句&#xff0c;echo off是什么意思&#xff1f;在bat中扮演着什么作用呢&#xff1f; A&#xff1a; echo off的意思是在批处理运行命令的时候不会一条一条的显示执行的命令&#xff0c;与之相匹配的还有echo on。 echo off 与echo on …

机器视觉康耐视Visionpro-脚本编写标记标识:点,直线,矩形,圆

显示标记标识的重要作用就是,对NG或者OK对操作机器视觉的人去看到具体位置缺陷或者NG坐标。 一.点CogPointMarker CogPointMarker PointMarker1 = new CogPointMarker();//创建对象,点CogPointMarker //注意运行工具 PointMarker1.X = 100; PointMarker1

基于FPGA的16QAM调制verilog代码

名称&#xff1a;FPGA的16QAM调制verilog 软件&#xff1a;Quartus 语言&#xff1a;Verilog 要求&#xff1a; 使用FPGA实现16QAM的调制&#xff0c;并进行仿真 代码下载&#xff1a;FPGA的16QAM调制verilog_Verilog/VHDL资源下载 代码网&#xff1a;hdlcode.com 部分代…

万界星空科技MES与WMS如何集成的?

传统制造业数字化转型正汹涌而来&#xff0c;要进一步提高产业发展质量&#xff0c;重塑制造业竞争优势&#xff0c;就必须加快发展数字化制造&#xff0c;加紧推动制造业的数字化转型。在这一数字化背景下&#xff0c;新一代科技技术的运用尤为重要。在具体实践中&#xff0c;…

工具及方法 - 二进制编辑软件

之前介绍过用Notepad和VSCode进行二进制文件编辑。 很多通用型的文本编辑器都会集成二进制文件编辑功能&#xff0c;或者使用插件等形式扩展此项功能。比如vi/vim等工具。 而且&#xff0c;作为文本编辑、二进制文件编辑一类的工具&#xff0c;数量众多&#xff0c;各有特色。…

msvcp140为什么会丢失?msvcp140.dll丢失的解决方法

msvcp140.dll 是一个动态链接库文件&#xff0c;它包含了 C 运行时库的一些函数和类&#xff0c;例如全局对象、异常处理、内存管理、文件操作等。它是 Visual Studio 2015 及以上版本中的一部分&#xff0c;用于支持 C 应用程序的运行。如果 msvcp140.dll 丢失或损坏&#xff…

redis安装问题

title: “Redis安装问题” createTime: 2022-01-04T20:47:0608:00 updateTime: 2022-01-04T20:47:0608:00 draft: false author: “name” tags: [“redis”] categories: [“install”] description: “测试的” title: redis安装可能遇到的错误 createTime: 2022-01-04T20:47…

如何在pycharm专业版使用conda虚拟环境

目 录 本文背景 前提条件 操作步骤 1.查看当前虚拟环境 2.创建一个新的虚拟环境 3.查看虚拟环境 4.切换虚拟环境 5.无依赖运行pandas代码 6.终端安装依赖 7.再次运行 本文背景 在经历了之前痛苦的环境各种报错的情况下&#xff0c;我终于知道如何有序地管理环境了 那…

SPA项目之登录注册--请求问题(POSTGET)以及跨域问题

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Vue的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.ElementUI是什么 &#x1f4a1;准备工作&…

数据结构与算法-时间复杂度与空间复杂度

数据结构与算法 &#x1f388;1.概论&#x1f52d;1.1什么是数据结构&#xff1f;&#x1f52d;1.2什么是算法&#xff1f; &#x1f388;2.算法效率&#x1f52d;2.1如何衡量一个算法的好坏&#xff1f;&#x1f52d;2.2算法的复杂度&#x1f52d;2.3时间复杂度&#x1f4d6;2…

Oracle 12c自动化管理特性的新进展:自动备份、自动恢复和自动维护功能的优势|oracle 12c相对oralce 11g的新特性(3)

一、前言: 前面几期讲解了oracle 12c多租户的使用、In-Memory列存储来提高查询性能以及数据库的克隆、全局数据字典和共享数据库资源的使用 今天我们讲讲oracle 12c的另外的一个自动化管理功能新特性:自动备份、自动恢复、自动维护的功能 二、自动备份、自动恢复、自动维护…

新思路,4.9+氧化应激相关基因构建风险模型

今天给同学们分享一篇氧化应激预后模型的生信文章“Construction of an oxidative stress-related lncRNAs signature to predict prognosis and the immune response in gastric cancer”&#xff0c;这篇文章于2023年5月31日发表在Scientific Reports期刊上&#xff0c;影响因…

【LeetCode】——双指针(快慢指针)/多指针

个人主页 代码仓库 C语言专栏 初阶数据结构专栏 Linux专栏 前言 大家好&#xff01;这是新开的LeetCode刷题专栏&#xff0c;这个专栏不只是随便的拿一些我练过的题讲解&#xff0c;而是总结我在刷题中的一些方法适用于一大类的题&#xff0c;是给大家提供这一大类题的解题…

STL-函数对象、谓词、常用算法

函数对象 函数对象概念 重载函数调用操作符的类&#xff0c;其对象常称为函数对象 函数对象使用重载的()时&#xff0c;行为类似函数调用&#xff0c;也叫仿函数 本质&#xff1a; 函数对象&#xff08;仿函数&#xff09;是一个类&#xff0c;不是一个函数 函数对象使用…

第一章:最新版零基础学习 PYTHON 教程(第十节 - Python 语句中的 – Python 如果否则)

在现实生活中,有时我们需要做出一些决定,并根据这些决定来决定下一步应该做什么。在编程中也会出现类似的情况,我们需要做出一些决定,并根据这些决定我们将执行下一个代码块。编程语言中的决策语句决定了程序执行流程的方向(控制流)。 Python 中的控制流类型 在Python…

计算π的近似值分数 ——python

利用格里高利公式&#xff1a; 计算 的近似值&#xff0c;直到最后一项的绝对值小于给定精度eps。 输入格式: 输入小于1且大于0的阈值。 输出格式: 输出满足阈值条件的近似圆周率&#xff0c;输出到小数点后6位。 输入样例: 在这里给出一组输入。例如&#xff1a; 0.0…

基于Quartz的可视化UI操作组件GZY.Quartz.MUI更新说明(附:在ABP中集成GZY.Quartz.MUI可视化操作组件)

NET Core 基于Quartz的UI可视化操作组件 GZY.Quartz.MUI 简介 像swaggerUI一样,项目入侵量小,仅需要在Startup中注入的UI组件 先上一张效果图,给没用过的兄弟们科普一下,如图: 更新内容 接下来,介绍一下更新了哪些功能. 1.修复采用数据库持久化数据的情况下,偶尔出现的异常…

一、vue2的基础语法巩固

一、定义&#xff1a;是一个渐进式的JavaScript框架 二、特点&#xff1a; 减少了大量的DOM操作编写 &#xff0c;可以更专注于逻辑操作分离数据和界面的呈现&#xff0c;降低了代码耦合度(前端端分离)支持组件化开发&#xff0c;更利于中大型项目的代码组织 vue2核心功能&a…