结构体,自定义类型

目录

结构体

结构体的声明

结构体的自引用

结构体的定义和初始化

结构体内存对齐

​编辑

结构体的对齐规则:

 为什么存在内存对齐?

修改默认对齐数

 结构体传参

位段

什么是位段

位段的内存分配

 位段的跨平台问题

枚举

联合(共用体)

联合体的大小计算


结构体

结构体的声明

结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。

结构体的关键字是struct 后面的Stu是结构体类型名,由我们自己定义,s1,s2是结构体变量,age和name是成员,即结构体变量中有各自的成员。

结构体还有一种特殊的声明,即匿名结构体。如下图:

 这种声明省略了结构体类型名,该声明不常用,因为他是一次性的,即在后面就不能继续对他定义了。

结构体的自引用

结构体的自引用就是在结构体成员中包含自身结构体类型的指针。

如上图, p指针可以用来指向下一节点。

结构体的定义和初始化

如上图,在初始化时,我们用花括号括起来,在里面赋值。初始化时,如果我们也可乱序定义。

先用.(成员运算符)然后加上成员名,再进行初始化即可,如下图。

 如下图,我们可以在结构体中嵌套结构体。

结构体内存对齐

如上图,可以看到,结构体的内存大小并不是平常的类型大小相加。这里涉及了结构体内存的对齐。

offsetof是一个宏,可以直接使用,是用来计算结构体成员相较于起始位置的偏移量的。

上图是S1占用空间的示意图,结合下面的规则,我们来分析。

分析:c1是第一个成员,起始位置从0开始。i是int型,与8相比,4为较小值,他的对齐数则为4,寻找最近的4的倍数,则从4开始占用,接着c2是char型,对齐数则为1,直接补在i后面即可,这3个成员中,对齐数分别为1,4,1,最大对齐数是4,总大小就是4的倍数,就需要再浪费3个空间。

结构体的对齐规则:

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

 为什么存在内存对齐?

 1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平        台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常。

  2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对       齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

     总的来说,结构体的内存对齐是拿空间来换取时间的做法。

举个例子:

红框是存储的数据,当我们 要读取i时,第一次只读取到前3个字节,需要读取两次才能完全读取到i,这是不对齐的情况。

当结构体内存对齐时,虽然中间的空间浪费了,但这时我们能一次读取到需要的数据,减少了花费的时间。 

所以在设计结构体的时候,我们既要节省空间,又要满足对齐,就需要让占用空间小的成员尽量集中在一起 。

修改默认对齐数

#pragma这个预处理指令,可以改变我们的默认对齐数。

如上图,第一个指令,把默认的对齐数改为4,最后一个指令,是恢复成原本的默认对齐数。 

 结构体传参

如上图,第一种是传值,第二种是传址。函数传参的时候,参数是要压栈的,会有时间和空间上的系统开销。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下能。因此,结构体传参的时候,要传结构体的地址。 

位段

什么是位段

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

1.位段的成员必须是int,unsigned int,或signed int。

2.位段的成员名后边有一个冒号和一个数字。

如上图, 是位段的声明,a占用了两个bit位的空间,位段能节省空间的占用。例如,假设a只可能是0,1,2,3,即二进制为00,01,10,11,如果我们不使用位段的方式,一个整形就要占32个bit位,实际上,位段也会浪费少量的空间。

位段的内存分配

1.位段的成员可以是int,unsigned int,或signed int或者是char(属于i整形家族)类型。

2.位段的空间上是按照需要以4个字节(int)或1个字节(char)的方式开辟的。

3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

 位段的跨平台问题

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

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

枚举

枚举,顾名思义就是一一列举,把可能的取值一一列举。

花括号中的内容是枚举类型的可能取值,也叫枚举常量。

这些可能取值都是有值的,默认从0开始,依次递增1。当然,在声明枚举类型的时候也可以赋初值。

联合(共用体)

联合也是一种特殊的自定义类型。

这种类型定义的变量也包含一系列的成员,特征是这些成员共用一块空间(所以联合也叫共用体)。

联合体的大小计算

联合体的大小并不是最大成员的大小。

联合体的大小至少是最大成员的大小。

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

如上图, 实际上,c是数组,因为有5个元素,占了五个字节,但他的对齐数依旧是1,而i的对齐数是4,比5大的4的倍数最小是8,所以大小就是8。 c和i和该联合体的起始地址都是一样的,他们共用一块空间,因此可以节省空间。

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

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

相关文章

文件管理:每个文件夹只移入1个文件要怎样操作?批量移动文件技巧

在文件管理过程中,有时要将多个文件分别移动到不同的文件夹中,每个文件夹只包含一个文件。这样的需求可能出现在许多场景中,比如整理文件、备份资料或者进行特定的项目处理。如果每个手动去移动文件就会出现丢失的情况,以及太过耗…

嵌入式系统

嵌入式系统 目前国内一个普遍认同的嵌入式系统定义是:以应用为中心、以计算机技术为基础,软件硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。(引用自《嵌入式系统设计师教程》) …

48.Go简要实现令牌桶限流与熔断器并集成到Gin框架中

文章目录 一、简介二、限流器与熔断器在微服务中的作用1.限流器 : 对某个接口单位时间内的访问量做限制2. 熔断器:当服务连续报错,超过一定阈值时,打开熔断器使得服务不可用 三、具体实现1. 限流器实现逻辑(以令牌桶算…

SQL Server——权限管理

一。SQL Server的安全机制 SQL Server 的安全性是建立在认证和访问许可两种安全机制之上的。其中.认证用来确定登录Sal Server 的用户的登录账户和密码是否正确.以此来验证其是否具有连接SQL Server 的权限;访问许可用来授予用户或组能够在数据库中执行哪…

软件设计师中级软考资料大全(一次过)

2023年下半年第一次参加软件设计师中级软考就过了,整理了下自己的备考资料和学习笔记,有需要可以下载 1.软件设计师中级软考全套官方参考资料及辅导书 软件设计师中级软考全套官方参考资料及辅导书 2.软件设计师中级软考历年真题解析(2004-2023) 软…

在springboot中引入参数校验

一、概要 一般我们判断前端传过来的参数&#xff0c;需要对某些值进行判断&#xff0c;是否满足条件。 而springboot相关的参数校验注解&#xff0c;可以解决我们这个问题。 二、快速开始 首先&#xff0c;我用的springboot版本是 3.1.5 引入参数校验相关依赖 <!--1…

2023五岳杯量子计算挑战赛数学建模思路+代码+模型+论文

目录 计算力网络&#xff08;CPN&#xff09;是一种新型的信息基础设施&#xff0c;完整论文代码见文末 问题描述 2.1 问题1 2.2 问题2 2.3 问题3 问题1的解答过程&#xff1a; 问题3的解答过程&#xff1a; 决策优化应用场景&#xff1a;人工智能模型超参数调优 背景信…

ELK(四)—els基本操作

目录 elasticsearch基本概念RESTful API创建非结构化索引&#xff08;增&#xff09;创建空索引&#xff08;删&#xff09;删除索引&#xff08;改&#xff09;插入数据&#xff08;改&#xff09;数据更新&#xff08;查&#xff09;搜索数据&#xff08;id&#xff09;&…

Kafka性能调优:高吞吐、低延迟的数据流

Apache Kafka作为一种高性能、分布式流处理平台&#xff0c;对于实时数据的处理至关重要。本文将深入讨论Kafka性能调优的关键策略和技术&#xff0c;通过丰富的示例代码为大家提供实际操作指南&#xff0c;以构建高吞吐、低延迟的数据流系统。 Broker 配置的优化 首先&#…

Cisco Packet Tracer配置命令——交换机篇

交换机VLAN配置 在简单的网络环境中&#xff0c;当交换机配置完端口后&#xff0c;即可直接应用&#xff0c;但若在复杂或规模较大的网络环境中&#xff0c;一般还要进行VLAN的规划&#xff0c;因此在交换机上还需进行 VLAN 的配置。交换机的VLAN配置工作主要有VLAN的建立与删…

【银行测试】第三方支付平台业务流,功能/性能/安全测试方法...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、第三方支付平台…

DSP外部中断笔记

中断原理 三部分 注意 &#xff0c;外部中断使能&#xff0c;PIE使能&#xff0c;CPU中断使能 外部中断有7个&#xff0c;PIE有12组&#xff0c;一个组有8个中断复用。只有一个CPU中断可执行。 外部中断原理 1、外部中断概述 外部中断结构图 外部中断XINT1对应的是0到31GPI…

在vue中深度选择器的使用

一、为什么要使用深度选择器 在vue中&#xff0c;当我们使用了第三方库中的组件时&#xff0c;想要更改一些样式&#xff0c;达到我们想要的效果&#xff0c;由于scoped的影响直接编写同名样式时&#xff0c;是覆盖不了组件内的样式的。 为了达到我们想要的效果&#xff0c;…

区块链实验室(28) - 拜占庭节点劫持区块链仿真

在以前的FISCO环境中仿真拜占庭节点攻击区块链网络。该环境共有100个节点&#xff0c;采用PBFT作为共识机制&#xff0c;节点编号分别为&#xff1a;Node0&#xff0c;Node&#xff0c;… &#xff0c;Node99。这100个节点的前2010区块完全相同&#xff0c;自区块2011开始分叉。…

Pytest+Allure生成自动化测试报告!

前言 在自动化测试中&#xff0c;有unittestHTMLTestRunner自动化测试报告&#xff0c;但是生成的测试报告不够美观详细&#xff0c;今天我们来学习一下PytestAllure生成自动化测试报告。 一&#xff1a;安装python中的allure依赖库 在dos窗口中&#xff0c;输入下面三个命令…

如何将idea中导入的文件夹中的项目识别为maven项目

问题描述 大家经常遇到导入某个文件夹的时候&#xff0c;需要将某个子文件夹识别为maven项目 解决方案

计算整数各位数字之和 C语言xdoj29

时间限制: 1 S 内存限制: 1000 Kb 问题描述: 假设n是一个由最多9位数字&#xff08;d9, …, d1&#xff09;组成的正整数。编写一个程序计算n的每一位数字之和 输入说明: 输入数据为一个正整数n 输出说明: 对整数n输出它的各位数字之和后换行 输入样例: …

金融行业文件摆渡,如何兼顾安全和效率?

金融行业是数据密集型产业&#xff0c;每时每刻都会产生海量的数据&#xff0c;业务开展时&#xff0c;数据在金融机构内部和内外部快速流转&#xff0c;进入生产的各个环节。 为了保障基础的数据安全和网络安全&#xff0c;金融机构采用网络隔离的方式来隔绝外部网络的有害攻击…

【动手学深度学习】(十)PyTorch 神经网络基础+GPU

文章目录 一、层和块1.自定义块2.顺序块3.在前向传播函数中执行代码 二、参数管理1.参数访问2.参数初始化3.参数绑定 三、自定义层1.不带参数的层2.带参数的层 四、读写文件1.加载和保存张量2.加载和保存模型参数五、使用GPU [相关总结]state_dict() 一、层和块 为了实现复杂神…

【EXCEL】offset函数

语法&#xff1a; offset(reference,row,column,[height],[width]) 例子&#xff1a;