C语言--结构体的大小与内存对齐,位段详解

一.前言

为了保证文章的质量和长度,小编将会分两篇介绍,思维导图如下,上篇已经讲过了概念部分,本文主要讲解剩余部分,希望大家有所收获🌹🌹

在这里插入图片描述

二.结构体的大小与内存对齐

2.1 存在对齐的原因

  1. 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
  2. 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
    原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存访问仅需要一次访问。(假设一个处理器总是从内存中取8个字节,则地址必须是8的倍数,那么就可以用一个内存操作来读或者写值了,否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中)

<总的来说>:结构体的内存对齐就是拿空间换取时间的做法

2.2 规则

  1. 结构体的第⼀个成员对齐到和结构体变量起始位置偏移量为0的地址处
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的⼀个对齐数 与 该成员变量大小的较小值
    ·VS 中默认的值为 8
    ·Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小
  3. 结构体总大小最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的整数倍
  4. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐的整数倍处,
    结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍

示例:
在这里插入图片描述
在这里插入图片描述

  • 在设计结构体时,我们如何做到既满足对齐,又节省空间呢?
    答:让占用空间小的成员尽量集中在一起 例如:
    在这里插入图片描述

2.3 #pragma修改默认对齐数

#pragma是一个预处理指令,用于修改默认对齐数,其中
在这里插入图片描述
示例如下:
在这里插入图片描述

  • 注意:别忘了
    对齐数 = 编译器默认的⼀个对齐数 与 该成员变量大小的较小值
    结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的整数倍。

三.结构体实现位段

3.1 什么是位段

位段是C语言中的一种特殊数据类型,它允许讲一个字节分成几个部分,并为每个部分指定特定的位数,以便在内存中存储和访问这些部分。
结构和联合中的int类型以及unsigned类型成员可以声明为指定的二进制位宽,这样的成员被称为位字段或者“位域”。

位段的声明和结构体是类似的,有两个不同:

  1. 位段的成员必须是int、unsigned或signed int,在C99中位段成员的类型也可以选择其他类型
  2. 位段的成员名后边有一个冒号和一个数字

在这里插入图片描述

3.2 位段的内存分配

  1. 位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的。
  2. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段
  3. 给定了空间后,在空间内部是从左向右使用还是从右向左使用是不确定的 注意:下面我给出的示例都是假设从右向左
  4. 当剩下的空间不足以存放下一个成员时,空间是浪费还是使用不确定假设:浪费

例1:
在这里插入图片描述
例2:
在这里插入图片描述

3.3 位段的跨平台问题

跟结构体相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题出现

  1. int位段被当成有符号数还是无符号数是不确定的
  2. 位段中最大位的数目不能确定(16位机器最大16 32位机器最大32 这意味着若在16位机器上写的数目超过16会出问题)
  3. 位段中的成员在内存中从左向右还是从右向左分配标准尚未定义
  4. 当一个结构包含两个位段,第二个位段成员比较大无法容纳于第一个位段剩余的位时,浪费or使用不确定

3.4 位段使用的注意事项

位段的几个成员共用同一个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的,所以不能对位段成员用&,这样也就不能用scanf直接给位段输入值,只能先输入放在一个变量中,然后赋值给位段的成员。

四.总结

结构体、位段的讲解在次就全部讲解完毕了,创作不易,希望大家多多支持,有什么想法欢迎讨论🌹🌹

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

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

相关文章

UnicodeDecodeError: ‘utf-8‘ codec can‘t decode bytes ... - python 报错解决方案

背景 加载数据集突然出问题&#xff0c; 详细报错为&#xff1a;UnicodeDecodeError: utf-8 codec cant decode bytes in position 606-607: invalid continuation byte 解决方案 源文件另存 UTF-8 版的 csv。 即可运行&#xff1a;

MQTT协议解析 : 物联网领域的最佳选择

1. MQTT协议概述 1.1 MQTT协议是什么 MQTT : Message Queuing Telemetry Transport 模式 : 发布 / 订阅主题优点 : 代码量小、低带宽、实时可靠应用 : 物联网、小型设备、移动应用MQTT 常用端口 : 1883 MQTT是一个网络协议&#xff0c;和HTTP类似&#xff0c;因为轻量简单&…

快速入门Zookeeper

Zookeeper ZooKeeper作为一个强大的开源分布式协调服务&#xff0c;扮演着分布式系统中至关重要的角色。它提供了一个中心化的服务&#xff0c;用于维护配置信息、命名、提供分布式同步以及提供组服务等。通过其高性能和可靠的特性&#xff0c;ZooKeeper能够确保在复杂的分布式…

「Mac玩转仓颉内测版1」入门篇1 - Cangjie环境的搭建

本篇详细介绍在Mac系统上快速搭建Cangjie开发环境的步骤&#xff0c;涵盖VSCode的下载与安装、Cangjie插件的离线安装、工具链的配置及验证。通过这些步骤&#xff0c;确保开发环境配置完成&#xff0c;为Cangjie项目开发提供稳定的基础支持。 关键词 Cangjie开发环境搭建VSC…

从0开始学习机器学习--Day20--优化算法的思路

确定执行的优先级(Prioritizing what to work on : Spam classification example) 在建立学习系统前&#xff0c;我们不仅要梳理框架&#xff0c;更重要的是我们要弄清楚有哪些事情是要优先做的&#xff0c;这可以帮我们节约大量的时间。 以垃圾邮件为例&#xff0c;按照之前…

H5播放器EasyPlayer.js 流媒体播放器是否支持npm(yarn) install 安装?

EasyPlayer.js H5播放器是一款功能强大的H5视频播放器&#xff0c;它支持多种流媒体协议播放&#xff0c;包括WebSocket-FLV、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WebRTC等格式的视频流。它不仅支持H.264和H.265编码格式&#xff0c;还具备实时录像、低延时直播等功能…

SpringCloud篇(微服务)

目录 一、认识微服务 1. 单体架构 2. 分布式架构 3. 微服务 3.1. 特点 3.2. 优点 3.3 缺点 二、微服务设计、拆分原则 1. AKF 拆分原则 2. Y轴&#xff08;功能&#xff09;关注应用中功能划分&#xff0c;基于不同的业务拆分 3. X轴&#xff08;水平扩展&#xff09…

【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇(下)

系列文章目录 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器&#xff08;上&#xff09; 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器&#xff08;下&#xff09; 【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇&#xff08;上&#xff09; 【…

ts 如何配置引入 json 文件

ts 如何配置引入 json 文件 参考文档&#xff1a; https://maxgadget.dev/article/how-to-import-a-json-file-in-typescript-a-comprehensive-guide 项目中有一个 .json 的文件是配置文件&#xff0c;如何引入到 ts 项目中 配置 tsconfig.json 文件&#xff0c;添加这两个 {…

Jenkins找不到maven构建项目

有的可能没有出现maven这个选项 解决办法&#xff1a;需要安装Maven项目插件 输入​Maven Integration plugin​

解决 “Error: listen EACCES: permission denied 0.0.0.0:80“ 错误

前言 在开发过程中&#xff0c;我们经常会遇到各种各样的错误。其中一个常见的错误是 Error: listen EACCES: permission denied 0.0.0.0:80。这个错误通常发生在尝试启动一个开发服务器时&#xff0c;服务器试图绑定到80端口&#xff0c;但由于权限不足而失败。本文将详细介绍…

华为2288HV2服务器安装BCLinux8U6无法显示完整安装界面的问题处理

本文记录了华为2288HV2服务器安装BCLinux8U6无法显示完整安装界面&#xff0c;在安装过程中配置选择时&#xff0c;右侧安装按钮不可见&#xff0c;导致安装无法继续的问题处理过程。 一、问题现象 华为2288HV2服务器安装BCLinux8U6时无法显示完整的安装界面&#xff0c;问题…

使用docker形式部署jumpserver

文章目录 前言一、背景二、使用步骤1.基础环境准备2.拉取镜像3.进行部署4.备份记录启动命令 前言 记录一下使用docker形式部署jumpserver服务的 一、背景 搭建一个jumpserver的堡垒机&#xff0c;但是发现之前是二进制文件部署的&#xff0c;会在物理机上部署污染环境&#x…

【SQL50】day 1

目录 1.可回收且低脂的产品 2.寻找用户推荐人 3.使用唯一标识码替换员工ID 4.产品销售分析 I 5.有趣的电影 6.平均售价 7.每位教师所教授的科目种类的数量 8.平均售价 1.可回收且低脂的产品 # Write your MySQL query statement below select product_id from Products w…

Mac如何将多个pdf文件归并到一个

电脑&#xff1a;MacBook Pro M1 操作方式&#xff1a; very easy 选中想要归并的所有pdf文件&#xff0c;然后 右键 -> quick actions -> Create PDF 然后就可以看到将所选pdf文件归并为一个pdf的文件了

elementUI 点击弹出时间 date-picker

elementUI的日期组件&#xff0c;有完整的UI样式及弹窗&#xff0c;但是我的页面不要它的UI样式&#xff0c;点击的时候却要弹出类似的日期选择器&#xff0c;那怎么办呢&#xff1f; 以下是elementUI自带的UI风格&#xff0c;一定要一个输入框来触发。 这是我的项目中要用到的…

PCA(主成分分析)算法的应用场景

PCA&#xff08;主成分分析&#xff09;算法的应用场景非常广泛&#xff0c;以下是一些主要的应用领域&#xff1a; 数据压缩&#xff1a; PCA可以将高维数据映射到低维空间&#xff0c;从而实现数据的压缩&#xff0c;减少存储空间和计算复杂度。这对于存储和传输大量数据的情…

优选算法第五讲:位运算模块

优选算法第五讲&#xff1a;位运算模块 1.常见的位运算总结2.判断字符是否唯一3.丢失的数字4.两整数之和5.只出现一次的数字II6.消失的两个数字 1.常见的位运算总结 2.判断字符是否唯一 链接: link class Solution { public:bool isUnique(string astr) {if(astr.size() >…

求平面连接线段组成的所有最小闭合区间

这个功能确实非常实用&#xff0c;我在过去开发地面分区编辑器时就曾应用过这一算法。最近&#xff0c;在新产品的开发中再次遇到了类似的需求。尽管之前已经实现过&#xff0c;但由于长时间未接触&#xff0c;对算法的具体细节有所遗忘&#xff0c;导致重新编写时耗费了不少时…

Spring Boot开发入门教程

简介 Spring Boot是一个开源的Java基础框架&#xff0c;用于创建独立、生产级的基于Spring框架的应用程序。通过Spring Boot&#xff0c;你可以轻松地创建独立的、生产级的Spring应用程序。 环境准备 Java开发环境&#xff1a;确保你的机器上安装了Java 8或更高版本。Maven…