详解结构体内存对齐及结构体如何实现位段~

目录

 ​编辑

一:结构体内存对齐

1.1对齐规则

1.2.为什么存在内存对齐

1.3修改默认对齐数

二.结构体实现位段

2.1什么是位段

2.2位段的内存分配

2.3位段的跨平台问题

2.4位段的应用

2.5位段使用的注意事项

 三.完结散花



 

                                            悟已往之不谏,知来者犹可追                                                        

创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免费的赞哟~ 

一:结构体内存对齐

1.1对齐规则

1.结构体的第一个成员对齐到和结构体变量起始位置偏移量为零的地址处~

2.其他变量要对齐到某个数字(对齐数) 的整数倍的地址处~

对齐数=编译器默认的一个对齐数与该成员变量较小值~

——VS中默认的对齐数是8~

——Linux中gcc没有默认的对齐数,成员变量的大小就是对齐数~

3.结构体总大小位最大对齐数(每个结构体成员变量都有自己对应的对齐数,取他们当中的最大值)的整数倍。~

4.如果嵌套了结构体的情况,嵌套的结构体变量总大小为自己成员变量的最大对齐数的整数倍,结构体的总大小就是所有成员变量的最大对齐数(含嵌套结构体中的成员变量中的对齐数)的整数倍~

举个栗子啦~

struct S1
{
char c1;
int i;
char c2;
};
printf("%d\n", sizeof(struct S1));

 你们猜一下该结构体变量的大小是多少呢~

接下来我们就根据上面讲的内存对齐规则来计算一下啦~

注意:以下测试均是在VS中!(其他编译器上可能会有不同的结果!)

让我们看一下运行结果啦~

让我们再看一看下面这个例子~

struct S2
{
char c1;
char c2;
int i;
};
printf("%d\n", sizeof(struct S2));

 运行效果也是这样呢~

1.2.为什么存在内存对齐

1. 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
2. 性能原因:
数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于,为了访问未对⻬的内存,处理器需要作两次内存访问;⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数,那么就可以⽤⼀个内存操作来读或者写值了。否则,我们可能需要执⾏两次内存访问,因为对象可能被分放在两个8字节内存块中。
3.总体来说:结构体的内存对⻬是拿空间来换取时间的做法。


那在设计结构体的时候,我们既要满⾜对⻬,⼜要节省空间,如何做到:

根据以上俩个栗子我们可以很容易的知道:


让占⽤空间⼩的成员尽量集中在⼀起就行啦~ 
 

1.3修改默认对齐数

#pragma 这个预处理指令,可以改变编译器的默认对⻬数。

如下操作就行啦~

#include <stdio.h>
#pragma pack(1)//设置默认对⻬数为1
struct S
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的对⻬数,还原为默认
int main()
{
//输出的结果是什么?
printf("%d\n", sizeof(struct S));
return 0;
}

结构体在对⻬⽅式不合适的时候,我们可以⾃⼰更改默认对⻬数啦~
 

二.结构体实现位段

2.1什么是位段

位段的声明和结构是类似的,有两个不同:
1. 位段的成员必须是 int、unsigned int 或signed int ,在C99中位段成员的类型也可以
选择其他类型。
2. 位段的成员名后边有⼀个冒号和⼀个数字

举个栗子啦~

struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};

 A就是⼀个位段类型。
那位段A所占内存的大小是多少?

2.2位段的内存分配

1. 位段的成员可以是 int 、unsigned int  、signed int 或者是 char 等类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的⽅式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使⽤位段

struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空间是如何开辟的?

 

2.3位段的跨平台问题

1. int位段被当成有符号数还是⽆符号数是不确定的。
2. 位段中最⼤位的数⽬不能确定。(16位机器最⼤16,32位机器最⼤32,写成27,在16位机器会
出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当⼀个结构包含两个位段,第⼆个位段成员⽐较⼤,⽆法容纳于第⼀个位段剩余的位时,是舍弃
剩余的位还是利⽤,这是不确定的。
总结:
跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

 

2.4位段的应用

下图是⽹络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要⼏个bit位就能描述,这⾥
使⽤位段,能够实现想要的效果,也节省了空间,这样⽹络传输的数据报⼤⼩也会较⼩⼀些,对⽹络
的畅通是有帮助的。


2.5位段使用的注意事项

位段的⼏个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的。
所以不能对位段的成员使⽤&操作符,这样就不能使⽤scanf直接给位段的成员输⼊值,只能是先输⼊放在⼀个变量中,然后赋值给位段的成员

struct A
{
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
};
int main()
{
struct A sa = {0};
scanf("%d", &sa._b);//这是错误的
//正确的⽰范
int b = 0;
scanf("%d", &b);
sa._b = b;
return 0;
}


 

 三.完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

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

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

相关文章

2.14作业

1.请编程实现二维数组的杨辉三角。 2.请编程实现二维数组计算每一行的和以及列和。 3.请编程实现二维数组计算第二大值。 4.请使用非函数方法实现系统函数strcat,strcmp,strcpy,strlen. strcat: strcmp: strcpy: strlen:

JVM性能调优 - 服务器性能排查(7)

在排查生产环境的性能问题时,以下是一些常见的步骤和技巧: 监控系统资源:使用系统监控工具(如top、htop、nmon等)来监控服务器的CPU使用率、内存使用率、磁盘IO等系统资源情况。这可以帮助你了解系统的整体负载情况,是否存在资源瓶颈。 分析日志:查看应用程序的日志文件…

操作系统——1.3 操作系统运行环境

1.3 操作系统运行环境 一、概念 操作系统运行机制总览 应用程序与内核程序 特权指令与非特权指令 内核态与用户态 CPU在内核态与用户态的切换 操作系统运行机制的总结 中断和异常总览 中断的作用 中断的类型 内中断的例子 外中断的例子 中断的分类&am…

【51单片机】利用【时间延迟】的原理规避【按键抖动问题】

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 本章是51LCD单片机设计的一个环节&#xff0c;完整可前往相应博客查看完整传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下…

PWR电源控制

PWR电源 PWR简介 PWR&#xff08;Power Control&#xff09;电源控制 PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能 可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上…

day40 Bootstrap文字背景颜色+网格系统(简单示例)

目录 Bootstrap5 颜色相关Bootstrap 网格系统网格类Bootstrap 自动布局等宽响应式列不等宽响应式列 Bootstrap5 颜色相关 <div class"container" style"background-color:plum"><h2>代表指定意义的文本颜色</h2><p class"text-m…

位运算总结(Java)

目录 位运算概述 位运算符 位运算的优先级 位运算常见应用 1. 给定一个数n&#xff0c;判断其二进制表示中的第x位是0还是1 2. 将数n的二进制表示中的第x位修改为1 3. 将数n的二进制表示中的第x位修改为0 4. 位图 例题&#xff1a;判断字符是否唯一 5. 提取数n的二进制…

【开源】SpringBoot框架开发企业项目合同信息系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 合同审批模块2.3 合同签订模块2.4 合同预警模块2.5 数据可视化模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 合同审批表3.2.2 合同签订表3.2.3 合同预警表 四、系统展示五、核心代码5.1 查询合同…

C++ JSON解析

JSON解析 JSONCPPC实现JSON解析器 JSONCPP JSONCPP源码链接&#xff1a;https://github.com/open-source-parsers/jsoncpp JSOCPP源码下载以后&#xff0c;首先复制一份include文件夹下的json文件夹&#xff0c;头文件留着后续备用。 使用Cmake生成项目。在IDE中编译jsoncpp_…

【算法分析与设计】环形链表

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次…

缓慢变化维 常用的处理方法

什么是缓慢变化维 维度 在数仓中&#xff0c;表往往会被划分成两种类型&#xff0c;一种是 事实表&#xff0c;另一种是维度表&#xff0c;举个例子&#xff0c;比如说&#xff1a; ❝ 2024年2月14日&#xff0c;健鑫在12306上买了两张火车票&#xff0c;每张火车票400元&…

TinUI v5预发布记录

TinUI v5预发布记录 前言新控件滚动选择框菜单按钮 新样式pre1pre2pre3 新功能导入字体文件 前言 TinUI是一个从2021年正式开始并一直维护到现在的小项目&#xff0c;中间经过了四代版本的更新。因为一些原因&#xff0c;2023年&#xff0c;TinUI-4后更新较少。 TinUI发展历程…

jmeter-问题二:JMeter进行文件上传时,常用的几种MIME类型

以下是一些常用的MIME类型及其对应的文件扩展名&#xff1a; 文本类型: text/plain: 通常用于纯文本文件&#xff0c;如 .txt 文件。 text/html: 用于HTML文档&#xff0c;即 .html 文件。 application/msword: Microsoft Word文档&#xff0c;即 .doc 和 .docx 文件。 图像…

英伟达市值超越谷歌!老黄隔空回应Altman的巨资筹款计划:没必要,真的没必要!

凭借算力上的霸主地位&#xff0c;英伟达正稳步成为科技领域的下一个巨头&#xff0c;在不久的15个月前&#xff0c;英伟达的市值还不足3000亿美元。然而&#xff0c;截至昨日&#xff0c;英伟达股价飙升使其市值达到了1.83万亿美元&#xff0c;超越了Alphabet&#xff08;谷歌…

传输层DoS

传输层是国际标准化组织提出的开放系统互联参考模型&#xff08;OSI&#xff09;中的第四 层。该层协议为网络端点主机上的进程之间提供了可靠、有效的报文传送服务。 平时我们所谈论的拒绝服务攻击大多是基于TCP的&#xff0c;因为现实中拒绝服务的对象 往往都是提供HTTP服务的…

Java类加载

Java类加载机制是Java虚拟机&#xff08;JVM&#xff09;的一个核心组成部分&#xff0c;它负责将Java类从不同的数据源&#xff08;如本地文件系统、网络等&#xff09;加载到JVM中&#xff0c;并为之生成对应的java.lang.Class对象。理解Java类加载机制对于深入理解Java运行时…

Python中多种生成随机密码超实用实例

前言 密码是信息安全的基石&#xff0c;它用于保护我们的账户、数据和隐私。为了确保密码足够强大&#xff0c;需要生成随机密码。在本文中&#xff0c;将讨论多种Python方法&#xff0c;用于生成随机密码的实用示例和技巧。 目录 ​编辑 前言 密码生成的要求 使用secrets…

创新S3存储桶检索:Langchain社区S3加载器搭载OpenAI API

在瞬息万变的数据存储和处理领域&#xff0c;将高效的云存储解决方案与先进的 AI 功能相结合&#xff0c;为处理大量数据提供了一种变革性的方法。本文演示了使用 MinIO、Langchain 和 OpenAI 的 GPT-3.5 模型的实际实现&#xff0c;重点总结了存储在 MinIO 存储桶中的文档。 …

C++ 音视频原理

本篇文章我们来描述一下音视频原理 音视频录制原理: 下面是对这张思维导图的介绍 摄像头部分: 麦克风采集声音 摄像头采集画面 摄像头采集回来的数据可以用RGB也可以用YUV来表示 图像帧帧率 一秒能处理多少张图像 图像处理 &#xff1a;调亮度 图像帧队列 :意思是将数据取…

【51单片机】LCD1602(江科大)

1.LCD1602介绍 LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符 显示容量:162个字符,每个字符为5*7点阵 2.引脚及应用电路 3.内部结构框图 屏幕: 字模库:类似于数码管的数…
最新文章