结构体,联合体与位段

1.结构体的内存对齐(计算结构体的大小)

1.1 为什么需要结构体内存对齐?

原因1:平台原因 

不是所有的硬件平台都能访问任意地址上的任意数据的;某些平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常。
比如,当一个平台要取一个整型数据时只能在地址为4的倍数的位置取得,那么这时就需要内存对齐,否则无法访问到该整型数据。

原因2: 性能原因

数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐内存,处理器需要作两次内存访问;而对齐的内存访问仅需一次。比如说下面这个整形i,我们想在一个32位机器访问它,一次读取四个字节,就需要两次才能访问完整的i,如果对齐了就只需要一次访问即可.

1.2 结构体内存对齐规则 

struct S {char c;int i;double d;
};

1.算出每个成员的对齐数(VS的默认对齐数是8,对齐数就是本身成员变量)

2.将每个元素对齐到较小值的整数倍下面.

3.通过最大对齐数知道大小最后的大小,比如说这个结构体的大小一定要是最大对齐数的整数倍,最大对齐数就是上面求出的较小值中的最大值.(是8),此时大小是16,正好是8的倍数,大多数情况下,此时的大小并不是最大对齐数的整数倍,这个时候我们只需补齐即可. 

1.3 设计结构体的技巧 

其实在我们设计结构体的时候,如果结构体成员的顺序设计得合理的话,是可以避免不必要的内存消耗的。
两个结构体的成员变量相同,但是成员变量的顺序不同,可能就会出现结构体的大小不同的情况: 

struct S1
{char a;char b;int c;
};struct S2
{char a;int c;char b;
};

这个时候我们发现,结构体S1占用的是8个字节,而结构体S2就占用了12个字节,所以我们在设计结构体的时候需要将占用内存小的元素放在一块儿,可以避免内存的浪费.

1.4 修改默认对齐数 

在VS2022中,我们可以自由的修改默认对齐数来满足我们的内存需求.

#pragma pack()

只需在pack中填入你设置的默认对齐数即可.

2.联合体 

2.1 什么是联合体

在C语言中,存在这样一个类型,可以让多个变量共用一块内存,这就是联合体.

使用场景:在某个变量不使用的时候可以使用其他变量.

缺点:在使用其他变量的时候会改变内存中的数据

union 联合名
{
成员表
};

2.2 联合体的创建方式(和结构体相似)

1.先创建模板,再定义变量

// 创建联合体模板union u
union u
{int i;char c;
};
// 使用该联合体模板创建两个变量a, b
union u a,b;

2.创建模板时同时定义变量

// 创建联合体模板union u的同时定义两个变量a、b
union u
{int i;char c;
};

3.匿名联合体

union
{int i;char c;
}a,b;

4.typedef

typedef union u
{int i;char c;
}U;
U a = {1,'a'};

2.3 初始化

U a;
a.i = 10;
U b = a;				        /* 1、把一个联合初始化为另一个同类型的联合; */
U c = {20};				        /* 2、初始化联合的第一个成员; */
U d = {.i = 30};                /* 3、根据C99标准,使用指定初始化器。 */

2.4 应用:判断机器的大小端

typedef union u
{int i;char c;
}U;
U u;
u.i = 0x12345678
//打印c,如果是78就是小端,如果是12就是大端

3.位段

3.1 什么是位段

位段是通过结构体来实现的一种以位(bit位)为单位的数据存储结构,它可以把数据以位的形式紧凑的储存,并允许程序员对此结构的位进行操作.这样可以节省空间.

注:位段里面的成员只能有整形家族来组成,否则会报错.位段后面分配的比特位不能超过原本类型的大小.

struct A
{int a:2;int b:5;int c:10;int d:30;
};

3.2 位段内存计算

我们以这个结构体举例

struct S
{char a:3;char b:4;char c:5;char d:4;
};
int main()
{struct S s = {0};printf("%d\n", sizeof(s));return 0;
}

实际上结果是3个字节,我们画图来看一下,这样相对直接使用结构体来说还是节省了不少空间的.

3.3 位段的跨平台问题

1.int型位段成员会被当成有符号数还是无符号数是不确定的
2.位段中最大位数目是不确定的(在16位机器上int型最大为16,而在32为机器上int型最大为3.32,如若写成27,那么16位机器就会出问题)
4.位段的成员在内存中到底是从左向右分配,还是从右向左分配尚未定义
5.当一个结构体包含两个位段,第二个位段比较大,无法容纳于第一个位段剩余的位时, 是舍弃剩余的位还是利用,是不确定的。
综上所述:位段是不跨平台的

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

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

相关文章

OpenCV项目开发实战之数码单反相机的技术方面介绍

在这篇文章中,我们将解释数码单反相机的各个技术方面。我们将解释焦距、光圈值、景深、光圈、快门速度、ISO 设置、图像稳定和自动包围曝光。 数码单反相机(或 DSLR – 数码、单反、镜头、反光)是一种数码相机,它使用反光镜机制将相机镜头发出的光线反射到光学取景器,或者…

35.浅谈贪心算法

概述 相信大家或多或少都对贪心算法有所耳闻,今天我们从一个应用场景展开 假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号? 广播台覆盖地区k1北京、上海、天津…

Qt5开发及实例V2.0-第二十二章-Qt.Quick Controls 2新颖界面开发

Qt5开发及实例V2.0-第二十二章-Qt.Quick Controls 2新颖界面开发 第22章 Qt Quick Controls 2新颖界面开发22.1 Qt Quick Controls 2简介22.1.1 第一个Qt Quick Controls 2程序22.1.2 Qt Quick Controls 2程序的构成 22.2 Qt Quick Controls 2与1的比较22.2.1 ApplicationWindo…

紫光展锐6nm国产5G处理器T820_国产手机芯片5G方案

紫光展锐T820是一款采用先进6nm EUV工艺的芯片,采用134三丛集八核心CPU架构,由1个主频为 2.7GHz 的 Arm Cortex-A76 大核和 3个主频为2.3GHz 的Arm Cortex-A76大核以及4个主频为2.1GHz的 Arm Cortex-A55组成 ,支持高达3MB 三级缓存&#xff0…

MySQL 篇

目录 1、数据库三范式 2、数据库事务的特性 3、MySQL数据库引擎 4、说说 InnoDB 与 MyISAM 的区别 5、索引是什么? 6、索引数据结构 7、MySQL 索引类型有哪些? 8、索引有什么优缺点? 9、索引设计原则 9、使用索引应该注意些什…

ubuntu 开启笔记本摄像头并修复画面颠倒问题

文章目录 基本环境状况: 没找到摄像头检查 opencv检查系统应用 键盘右侧,硬件层面开启摄像头画面镜像问题 基本环境 笔记本: 联想拯救者 系统: ubuntu 22.04 状况: 没找到摄像头 检查 opencv 使用 cv::VideoCaptu…

实验室安全教育与考试

目录 我的错题(2个)新知识题目(10个)刚开始不太理解的题目(10个)写在最后(免责声明) 我的错题(2个) 18.发生电气火灾时可以使用的灭火设备包括:&…

【100天精通Python】Day65:Python可视化_Matplotlib3D绘图mplot3d,绘制3D散点图、3D线图和3D条形图,示例+代码

1 mpl_toolkits.mplot3d 功能介绍 mpl_toolkits.mplot3d 是 Matplotlib 库中的一个子模块,用于绘制和可视化三维图形,包括三维散点图、曲面图、线图等。它提供了丰富的功能来创建和定制三维图形。以下是 mpl_toolkits.mplot3d 的主要功能和功能简介&am…

银行竞争度-地级市HHI+CRn(2000-2022年)

地级市的银行竞争度数据,其计算方法参考了姜付秀(2019)的方法。原始来源于中国银监会的金融许可证信息,用以测算各银行在各城市的年度分支机构数量,进而构建各城市银行业的赫芬达尔一赫希曼指数(HHI&#x…

《动手学深度学习 Pytorch版》 7.1 深度卷积神经网络(AlexNet)

7.1.1 学习表征 深度卷积神经网络的突破出现在2012年。突破可归因于以下两个关键因素: 缺少的成分:数据 数据集紧缺的情况在 2010 年前后兴起的大数据浪潮中得到改善。ImageNet 挑战赛中,ImageNet数据集由斯坦福大学教授李飞飞小组的研究人…

js对象属性

在面向对象的语言中有一个标志,那就是都有类,通过类可以创建任意多个相同属性、方法的对象。在js中没有类的存在,所以js中的对象,相对于类语言中对象有所不同。 js中定义对象为:“无序属性的集合,其属性可…

虹科案例 | LIN/CAN总线汽车零部件测试方案

文章来源:虹科汽车电子 点此阅读原文 虹科的LIN/CAN总线汽车零部件测试方案是一款优秀的集成套装,基于Baby-LIN系列产品,帮助客户高效完成在测试、生产阶段车辆零部件质量、功能、控制等方面的检测工作。 1、汽车零部件测试的重要性&#xf…

乐鑫科技全球首批支持蓝牙 Mesh Protocol 1.1 协议

乐鑫科技 (688018.SH) 非常高兴地宣布,其自研的蓝牙 Mesh 协议栈 ESP-BLE-MESH 现已支持最新蓝牙 Mesh Protocol 1.1 协议的全部功能,成为全球首批在蓝牙技术联盟 (Bluetooth SIG) 正式发布该协议之前支持该更新的公司之一。这意味着乐鑫在低功耗蓝牙无线…

排序:冒泡排序算法分析

1.交换排序 基于“交换”的排序︰ 根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。 交换排序包括冒泡排序和快速排序。 2.冒泡排序 1.算法原理 从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即 A [ i − 1 ] > A [ i ] A[i-1]&…

【Java 基础篇】Java Stream 流详解

Java Stream(流)是Java 8引入的一个强大的新特性,用于处理集合数据。它提供了一种更简洁、更灵活的方式来操作数据,可以大大提高代码的可读性和可维护性。本文将详细介绍Java Stream流的概念、用法和一些常见操作。 什么是Stream…

API网关是如何提升API接口安全管控能力的

API安全的重要性 近几年,越来越多的企业开始数字化转型之路。数字化转型的核心是将企业的服务、资产和能力打包成服务(服务的形式通常为API,API又称接口,下文中提到的API和接口意思相同),从而让资源之间形…

怎么在OPPO手机桌面上添加文字?便签桌面插件添加教程

很多年轻女性在选择手机时,都比较青睐于设计时尚靓丽、轻薄且续航好、系统流畅、拍照清晰的OPPO手机,并且OPPO为不同的用户提供了高中低不同价格档位的手机型号,能够满足绝大多数女性消费者的使用需求。 不过有不少OPPO手机用户表示&#xf…

hot100-哈希

1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按…

关于项目、项目集、项目组合以及运营管理之间的关系

什么是项目? 【项目】这个名词,其实各位一点都不陌生,各位从小到大在各种报章杂志,甚至是每晚的新闻播报里面,每每都会看到或是听到【项目】这个词语,甚至在各位进入大学,或是研究生的阶段里就…

AttributeError: type object ‘mmap.mmap‘ has no attribute ‘ACCESS_READ

在使用mmap时,运行项目,出现了报错:AttributeError: type object ‘mmap.mmap’ has no attribute ACCESS_READ 源代码是这样的: with mmap(f.fileno(), lengthfile_size, accessmmap.ACCESS_READ) as data 此时我的头文件引用是…