结构体,联合体与位段

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,一经查实,立即删除!

相关文章

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…

《动手学深度学习 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) 正式发布该协议之前支持该更新的公司之一。这意味着乐鑫在低功耗蓝牙无线…

【Java 基础篇】Java Stream 流详解

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

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

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

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

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

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

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

基于人脸5个关键点的人脸对齐(人脸纠正)

摘要:人脸检测模型输出人脸目标框坐标和5个人脸关键点,在进行人脸比对前,需要对检测得到的人脸框进行对齐(纠正),本文将通过5个人脸关键点信息对人脸就行对齐(纠正)。 一、输入图像…

ORB-SLAM2实时稠密地图,解决运行报段错误(核心已转储)运行数据集时出现段错误,出现可视化界面后闪退(添加实时彩色点云地图+保存点云地图)

高翔的稠密建图仓库 1. git clone https://github.com/gaoxiang12/ORBSLAM2_with_pointcloud_map.git 2. 去ORB SLAM2里拷贝Vocabulary到/home/cgm/ORBSLAM2_with_pointcloud_map/ORB_SLAM2_modified文件夹下 3. 删除一些build文件夹 删除ORB_SLAM2_modified/Thirdparty/DB…

哈希 -- 位图、布隆过滤器、海量数据处理

目录 一、位图1.1 经典题目1.2 位图概念1.3 位图的应用1.4 关于位图的三个经典问题 二、布隆过滤器2.1 布隆过滤器的提出2.2 布隆过滤器的概念2.3 布隆过滤器的插入2.4 布隆过滤器的查找2.5 布隆过滤器删除2.6 代码实现2.7 布隆过滤器的优点2.8 布隆过滤器的缺陷2.9 布隆过滤器…

TongWeb8下应用忙碌线程监控

问题 : 在系统运行过程中发现TongWeb进程占用CPU过高,需要分析是应用哪里引起的问题。 分析过程(仅限Linux环境): 1. 通过top命令查看TongWeb的java进程占用的CPU情况。 查看误区:不要以为java进程CPU占到398%就是高&#xff0…

MySQL学习笔记12

MySQL 查询语句: 1、查询五子句:(重点) mysql> select */字段列表 from 数据表名称 where 子句 group by 子句 having 子句 order by 子句 limit 子句; 1)where 子句;条件筛选。 2)group…

golang 通过案列感受下内存分析

package main // 声音文件所在的包,每个go文件必须有归属的包 import ("fmt" )// 引入程序中需要用的包,为了使用包下的函数,比如:Printinfunc exchangeNum(num1 int, num2 int){var t intt num1num1 num2num2 t }…