结构体,联合体与位段

news2024/11/23 15:49:36

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.coloradmin.cn/o/1038310.html

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

相关文章

黑马程序员2023新版JavaWeb企业开发全流程学习笔记(涵盖Spring+MyBatis+SpringMVC+SpringBoot等)

目录 零、Web开发一、HTML-CSS初识Web前端Web前端课程安排小结 HTML、CSS介绍HTML快速入门HTML小结VS Code开发工具基础标签 & 样式-合集(拟新浪微博为例)标题排版样式超链接 正文排版布局 表格、表单标签表格标签表单标签表单项 二、JavaScriptJS基…

车载软件架构 —— AUTOSAR Vector SIP包(三)

车载软件架构 —— AUTOSAR Vector SIP包(三) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在…

【计算机网络笔记四】应用层(一)DNS域名解析

因特网的域名空间是一棵倒着生长的树,各级域名由其上一级域名管理机构管理。 这种按等级管理的命名方法便于维护名字的唯一性,并且容易设计出一种高效的域名查询机制。 注意:域名只是个逻辑概念,并不代表计算机所在的物理地点 域…

10.mysql系统配置与启动选项

title: “mysql系统配置与启动选项” createTime: 2022-03-06T15:52:4108:00 updateTime: 2022-03-06T15:52:4108:00 draft: false author: “ggball” tags: [“mysql”] categories: [“db”] description: “” 启动选项与系统变量 启动选项 长格式与短格式 在执行启动脚…

el-tree实现表格方式菜单

<template><div class"table"><!-- default-expand-all 默认展开全部数据 --><!-- expand-on-click-node 只有点击箭头才会收缩节点 --><!-- check-on-click-node 点击文本选中 --><!-- show-checkbox 复选框 --><div class&…

Mybatis-分页插件

Mybatis-分页插件 前言一、分页插件的使用步骤1.添加依赖2.配置分页插件3. 分页插件的使用 前言 可以通过分页插件在实现以下前端样式时更加方便&#xff1a; 首页 上一页 2 3 4 5 6 下一页 末页 limit index,pageSize pageSize&#xff1a;每页显示的条数 pageNum&#xff…

TVP 专家谈腾讯云 Cloud Studio:开启云端开发新篇章

点击链接了解详情 导语 | 近日&#xff0c;由腾讯云 TVP 团队倾力打造的TVP 吐槽大会第六期「腾讯云 Cloud Studio专场圆满落幕&#xff0c;6 位资深的 TVP 专家深度体验腾讯云 Cloud Studio 产品&#xff0c;提出了直击痛点的意见与建议&#xff0c;同时也充分肯定了腾讯云 Cl…

虚拟机桥接模式下没有无线网卡选项

我以为是雷电模拟器占用了网卡的缘故&#xff0c;但想起之前可能修改了无线网卡的某些内容&#xff0c;于是到网络属性里面查看。 如下所示&#xff0c;原来是之前我不小心把这个红箭头指向的项目取消勾选了。

【数据结构】B树、B+树的知识点学习总结

目录 1、B树 1.1 定义 1.2 特性 1.3 查找操作 1.4 插入操作 1.5 删除操作 2、B树 2.1 定义 2.2 特性 3、B树与B树的对比 1、B树 1.1 定义 B树是一种平衡树数据结构&#xff0c;用于存储和访问大量数据。B树的每个节点可以存储多个键值&#xff0c;节点中的键值按照…

虚幻4学习笔记(15)读档 和存档 的实现

虚幻4学习笔记 读档存档 B站UP谌嘉诚课程&#xff1a;https://www.bilibili.com/video/BV164411Y732 读档 添加UI蓝图 SaveGame_UMG 添加Scroll Box 修改Scrollbar Thickness滚动条厚度 15 15 勾选 is variable 添加text 读档界面 添加背景模糊 添加UI蓝图 SaveGame_Slot …

Linux初识+环境部署

文章目录 版权声明Linux初识Linux的诞生Linux内核Linux发行版 环境部署vmcentosWSL-Ubuntu 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用&…

100天精通Python(可视化篇)——第102天:Pyecharts绘制多种炫酷关系网图参数说明+代码实战

文章目录 专栏导读一、关系网图介绍1. 关系网图是什么&#xff1f;2. 关系网图的应用场景 二、关系网图类配置选项1. 导包2. add函数3. 关系网络图的节点4. 关系网络图的边5. 节点分类的类目 三、关系网图实战1. 普通关系网图2. 复杂关系网图3. 带边信息的关系网络图4. 微博转发…

2023 年解锁物联网端点安全

物联网 (IoT) 和端点安全的融合已成为小型企业的关键焦点。这些企业正在努力保护其数字环境。物联网的集成彻底改变了运营流程。通过这样做&#xff0c;它们为创新和增长提供了前所未有的机会。然而&#xff0c;它也带来了无数的安全挑战&#xff0c;需要采取强有力的保护措施。…

(一)NIO 基础

&#xff08;一&#xff09;NIO 基础 non-blocking io&#xff1a;非阻塞 IO 1、三大组件 1.1、Channel & Buffer Java NIO系统的核心在于&#xff1a;通道&#xff08;Channel&#xff09;和缓冲&#xff08;Buffer&#xff09;。通道表示打开到 IO 设备&#xff08;例…

开关电源-交流220V降压电路-电阻电容降压原理

阻容降压原理 电容电阻降压的原理其实比较简单。它的工作原理是电容在交流信号的情况下&#xff0c;产生容抗来限制最大的工作电流。说白了就是电容使用它自己的通交流阻直流的性能&#xff0c;在交流信号输入时电容产生容抗。我们通过他的这个特性&#xff0c;可以设计出&…

Java基础(一)——Hello World,8种数据类型,键盘录入

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

腾讯mini项目-【指标监控服务重构-会议记录】2023-07-21

2023-07-21 组长会议纪要 A组 文档学习差不多&#xff0c;还没掌握如何使用sdk进行上报venus启动服务的3个ToDo 添加什么错误处理 ErrHandler &#xff1a; fiber的错误处理&#xff0c;是运行过程Handler中的错误&#xff0c;在全局的ErrHandler&#xff0c;进行错误处理&am…

APP备案公钥,指纹获取

APP备案公钥&#xff0c;指纹获取 下载已有的apk&#xff0c;文件后缀名改为zip 2&#xff0c;找到META-INF文件夹&#xff0c;然后再找到文件CERT.RSA 后缀改名为CERT.p7b 3&#xff0c;双击后&#xff1a; 4&#xff0c;双击右侧证书点开&#xff1a;显示颁发给。 5&#xf…

Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢

一、前言 Unity 引擎宣布自 2024 年 1 月 1 日起&#xff0c;将根据游戏安装量对开发者进行收费。官网通知如下 收费模式如图 这张图的大致意思就是&#xff0c; 从2024年1月1日开始&#xff0c;Unity将对所有达标的用户&#xff08;开发者&#xff09;根据游戏安装量征收“安…

游戏扫码登录+多功能工具箱 微信小程序源码

一个集合了多种实用功能的微信小程序&#xff0c;这个微信小程序源码不仅具备美观的界面设计&#xff0c;还拥有许多实用的功能&#xff0c;而且最重要的是&#xff0c;它无需服务器和域名&#xff0c;所有功能都无需API接口&#xff0c;因此不用担心功能失效的问题。这意味着&…