首页 > 其他分享 >二十七步天注定,逆流河上任我行-自定义类型:结构体

二十七步天注定,逆流河上任我行-自定义类型:结构体

时间:2024-11-23 14:34:04浏览次数:11  
标签:步天 struct 自定义 int 成员 任我行 内存 对齐 结构

---当你累到不行,还继续坚持,那就是梦想的力量

  • 1.结构体类型的声明
  • 2.结构体变量的创建和初始化
  • 结构成员访问操作符
  • 结构体内存对齐
  • 结构体传参

1:结构体类型的声明

struct tag 

{

      member-list;

} variable-list;

如果说描述一个人的身份数据:

struct stu

{

  char name[20];

   int    age;

   float  high;

   char  sex[5];

}

2:结构体变量的创建和初始化

1:

按结构体成员顺序初始化

31939b7678da4863b761c0b6fd721d94.png

 2:

结构的特殊声明:

在声明结构的时候可以不完全声明

struct

{

int a;

char b;

float c;

}x;

结构在声明的时候,省略掉了结构体标签(tag)     所以,定义结构体的时候,最好不要使用匿名结构体。

3:

结构的自引用 :

如果一个结构体中包含同类型的成员是否可以呢?

struct node

{

int data;

struct node next;

};

我们仔细想一想,如果是这样,那这样结构体的变量大小是多少呢?无穷大?所以是不合理的。

正确的自引方式为:

struct node 

{

int data;

struct node * next;

};

3.结构体内存对齐

我们了解内存对齐才能知道怎么计算结构体的大小

1.对齐规则

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

2.其他成员变量要对齐到对齐数的整数倍地址

(对齐数:编译器默认的对齐数(VS的为8)与该成员变量大小相比的较小值)

3.结构体的总大小为结构体成员中的成员变量最大(所占字节最大)的一个的对齐数的整数倍

4.如果嵌套的结构体的情况,也就是结构体中有一个成员也是结构体,嵌套的结构体成员对齐到自己成员中最大的对齐数的整数倍处,而外面的结构体的整体大小,就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍

如果是在VS中,其实对齐数就是成员变量所占字节数(int: 4 ,char: 1 ,double :8 ,float : 4)与8相比的较小值

e46d72403ad0424e8be9b2736cf61717.png

d9e26869b08a4556a599a4f49e23d493.png

 首先,c1对齐零,然后int i要对齐它的最小整数倍上面,最后是9个字节,不是最大对齐数(也就是int为4)的整数倍所以要一直加到12,为四的整数倍,则12是它的,结构体的大小。

为什么存在内存对齐?

平台原因:

不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常

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

比如一个处理器,总是从内存中读取八个字节,则地址必须是八的倍数。如果我们能保证将所有double类型的数据的地址都对齐成八的倍数,那么就可以用一个内存操作来读,或者写值了,否则我们可能需要执行两次内存访问,因为对象可能被分在两个八字节内存块中

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

所以我们要让占空间小的成员尽量集中在一起,这样我们既能满足对齐,又能节省空间

a7b18f9819fb42bcb1c450a0cbd55fa6.png

修改默认对齐数

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

6f113a655da94c259f9536bbf48087c3.png

 在结构体对齐方式不合适的时候,我们可以更改默认对齐数

4.结构体传参

fa91a622eb3e45c8a010f9ca1681a3fe.png

 相比于func1,func2更好

因为函数传参的时候,参数是需要压栈的,会有时间和空间上的系统开销,如果传一个结构体的对象,结构体对象很大的时候,参数压栈的系统开销就会变大,会导致性能的下降

结论:结构体传参的时候要传结构体的地址

 

 

 

标签:步天,struct,自定义,int,成员,任我行,内存,对齐,结构
From: https://blog.csdn.net/2402_87310323/article/details/143984422

相关文章

  • 基于STL的自定义栈与队列实现:灵活选择底层容器的模板设计
    文章目录代码模板设计主要成员函数底层容器的选择模板设计底层容器的选择关于stack的示例代码关于queue的示例代码前言:在本文中,我们将分析一个模拟C++标准模板库(STL)栈的自定义实现以及模仿C++标准模板库(STL)队列的自定义实现。该stack类模板允许在底层容器的选择......
  • 推荐15个 Vue 常用自定义指令,含实现原理与使用方式
    前言Vue.js是一个流行的前端框架,它的核心理念是通过指令(Directives)来扩展HTML的能力。尽管Vue.js已经内置了一些非常实用的指令(比如v-if,v-show,v-for等),但有时候我们还是需要创建自定义指令来满足特定的需求。今天我们就来聊聊Vue常用的自定义指令,它们能让你的......
  • 提现生成器【APP】自定义生成小游戏提现截图
    今天发个避坑帖!首先看看下面这种收益图,你们肯定见过不少!‘割割’们让你上车,必须得有一些吸引你的东东啊,不然怎么割你吗?其实这种截图都是软件生成的,我网站上分享过非常多的类似软件,什么聊天记录生成的啊,什么ZFB,微信零钱转账记录,余额多少啊。。。。。都可以生成。像这种......
  • C#的自定义Tip窗体 - 开源研究系列文章
          上次编写了自定义的提示和对话框窗体,这次记录的是自定义的Tip窗体,用于显示提示操作。有时间没编程了,这次就当进行了记录。 1、项目目录;  2、源码介绍;1)实现;  2)应用;  3、运行界面;  4、使用介绍......
  • Nginx根据返回的错误码,自定义错误页面回显
    在/data/nginx/html/uhn目录下创建一个error.html[root@localhost~]#echo"errorpage">/data/nginx/html/uhn/error.html然后修改配置文件,将 500502503504404的错误页面指向/error.html页面[root@localhost~]#cdweb[root@localhostconf.d]#viuhn.confserver......
  • Spring Cloud --- Gateway自定义全局过滤器
    Gateway自定义全局过滤器介绍全局过滤器对所有路由生效。新建类MyGlobalFilter并实现GlobalFilter,Ordered两个接口自定义接口调用耗时统计的全局过滤器@Component@Slf4jpublicclassMyGlobalFilterimplementsGlobalFilter,Ordered{publicstaticfinalS......
  • vTESTstudio系列14--vTESTstudio中自定义函数介绍1
    在上篇vTESTstudio系列的文章中,我们基于osek_tp.dll实现了诊断的发送和回复的最基本的脚本,但是我们可以看出来,这样的脚本是不具有普适性的,为了生成一个普适性的诊断请求回复的函数,接下来本系列的几篇文章会开始介绍一些优自定义的小函数,Let'sGo!!!目录1.自定义函数:1.1字符......
  • ArcGIS002:软件自定义设置
    摘要:本文详细介绍安装arcgis10.2后软件自定义设置内容,包括工具条的启用、扩展模块的启用、如何加载项管理器、快捷键设置、样式管理器的使用以及软件常规设置。一、工具条的启用依次点击菜单栏【自定义】->【工具条】,根据工作需求勾选上常用的工具条。勾选后相应工具条自动......
  • ultralytics yolo 训练及推理自定义人脸关键点数据 - python 实现
            Ultralytics YOLO 是计算机视觉和ML领域专业人士的高效工具。    深度学习的关键点任务也是基础和常见任务,所以这里进行基于ultralyticsyolo自定义关键点数据集的模型训练和模型推理。    根据需求,可能会发布其webui版本,现在已经发布......
  • Java自定义函数查看OS的File Cache — 从原理到实战
    全文目录:开篇语......